본문 바로가기

개발일지/Java + Spring

[Java] 생성자(Constructor), this() 생성자, 초기화 블록

생성자(Constructor)

new 연산자에 의해서 객체 생성을 할 때 단 한 번 호출되는 단위(아래에서 9번)이다. 생성자를 이용해서 객체 생성(20, 26, 32)을 하면 Heap 영역에 매 번 새로운 객체가 생성되는 것이다. 이전까지 파라미터가 없는 빈 생성자를 이용해 객체를 생성했는데 클래스에 생성자가 하나도 정의 되지 않았을 땐 컴파일러가 알아서 처리를 했다. 하지만 클래스에 인자값(11, 14)이 있는 생성자가 하나라도 있을 시 컴파일러가 처리를 못 하기에 반드시 빈 생성자(9)도 함께 정의해 주어야 한다. 인자값이 없다면 안 해도 됨!

 

▼ 11, 14번이 있는데 9번이 없다면 20번에서 생성자를 만들 수 없다. 

Console ...

person1.name = null, person1.age = 0, person1.height = 0, person1.weight = 0
person2.name = null, person2.age = 30, person2.height = 0, person2.weight = 0
person3.name = Good Man, person3.age = 0, person3.height = 0, person3.weight = 0

 

생성자를 따로 정의하는 이유는 객체를 생성할 때 멤버 변수 값을 쉽게 초기화 하기 위해서이고, 오버로딩 제공 및 하나의 클래스 안에서 여러 개 생성자를 정의 할 수 있다. 

 

코드를 뜯어 보자면 20번은 인자가 비어있고 26, 32번에서 보내는 인자값을 Person 클래스의 11, 14번에서 받아준다. 그리고 각 메소드를 실행해 위쪽 인스턴스 멤버 변수에 넣어준다(this는 자기 자신 클래스의 변수=멤버변수를 가르킨다). 객체 생성을 3번 했고 그럴 때마다 새로운 Heap에 생성이 된 것이니까 서로의 값을 공유하지 않는다. 

 


내가 헷깔려서 덧붙임 . . .

 

자바에서 클래스는 멤버로 속성을 표현하는 필드(field)와 기능을 표현하는 메소드(method)로 나뉩니다. 여기서 필드는 변수를 의미 합니다. 클래스는 생성된 객체의 변수를 초기화 해주기 위해서 특별한 메소드인 생성자(Construtor)를 가집니다.  클래스를 가지고 객체 생성을 하면 즉시 메모리에 생성이 되지만 인스턴스 변수가 아직 초기화 되지 않은 상태입니다. 이 객체생성을 하는 동시에 인스턴스 변수를 원하는 값으로 초기화 할 수 있는 생성자 라는 메소드를 제공합니다. 여기서 생성자의 이름은 해당 클래스명과 같아야 합니다. 

 

class Car {                    // 클래스 이름
    private String modelName;  // 필드
    private int modelYear;     // 필드

    Car(String modelName, int modelYear) { // 생성자
        this.modelName = modelName;
        this.modelYear = modelYear;
    }
 
    public String getModel() { // 메소드
        return this.modelYear + "년식 " + this.modelName + " " + this.color;
    }
}

 

 

참고는 아래 주소! 밑에서 더욱 자세한 설명을 보실 수 있습니다.

 

코딩교육 티씨피스쿨

4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등

tcpschool.com

 


this()생성자

 

this는 자기 자신의 객체를 참조하는 레퍼런스 변수이다. 생성자/메소드의 블록 안에 있는 로컬 변수 이름이 멤버 변수의 이름과 같거나, 이 변수가 멤버변수임을 알리기 위해 지정한다. 그렇지 않으면 멤버변수와 이름만 같은 로컬 변수가 되기 때문인데 이 때문에 해당 블록이 종료되면 같이 사라질 것이다. 하지만!! this()는 코드의 간결성을 위해 자기 자신 클래스의 다른 생성자를 호출하기 위해서 사용된다. 

 

생성자를 여러 개 만들어서 멤버변수를 초기화 할 때 멤버변수 초기화를 모든 생성자에서 정의하면 중복코드가 만들어진다. 따라서 멤버 변수 초기화를 특정 생성자에 미리 정의하고, 다른 생성자에서는 그저 호출만 하면 되기 때문에 편리하고 코드가 간결해진다. 

 

쉽게 말해서 생성자 안에서 반복적인 코드를 미리 정의해두고, 다른 생성자들 안에서 this()를 통해서 불러다 쓸 수 있게 만든다.  중복 코드 제거 역할을 한다. 덧붙여 말하자면 this() 생성자는 반드시 생성자의 첫줄에서 실행해야한다.

 

 

9~12 사용할 멤버변수들을 초기화 하기 위해서 this()로 다른 생성자 호출 및 초기화 한다. 인자가 전송되어 오지 않는 것까지 임의로 초기화를 해준다. this()는 무조건 첫 라인에서 호출되어야 한다.

 

9~28 여러개의 생성자를 정의했다. 실질적인 초기화 작업은 마지막 생성자  22~28에서 정의하고 있으며, 다른 생성자들은 this() 생성자를 호출해서 작업을 하고 있다.

 

위에서 마지막 초기화 작업( 22~28 )을 쉽게 하는 방법이 있다. Alt + Shift + S를 누르고 Generate Constructor using Fields를 클릭 후 모든 걸 체크하고 OK를 누르면 끝!

 

31~62 각각의 다른 생성자를 호출해서 객체생성을 한 후 초기화된 멤버변수 값을 확인한다.

가격 : 100, 크기 : 32, 주소 : 상계동, 종류 : 아파트
가격 : 300, 크기 : 32, 주소 : 상계동, 종류 : 아파트
가격 : 300, 크기 : 40, 주소 : 상계동, 종류 : 아파트
가격 : 300, 크기 : 40, 주소 : 서초동, 종류 : 아파트
가격 : 300, 크기 : 40, 주소 : 서초동, 종류 : 빌라

초기화 블록

good의 static 초기화 블록 실행
good의 인스턴스 초기화 블록 실행
good의 인스턴스 초기화 블록 실행
good의 인스턴스 초기화 블록 실행
main

 

인스턴스 블록이 초기화를 먼저 했지만 static 블록이 먼저 저장되기 때문에 가장 먼저 출력이 된다. 클래스가 로딩이 될 때 한 번만 실행이 된다. 객체를 여러 번 생성해도 모두 같은 값이라는 걸 알아야 한다. 그와 반대로 인스턴스 값은 객체생성을 할 때마다 다른 레퍼런스 값을 가지고 있는 인스턴스 블록이 호출된다.