생성자가 존재하는 이유
이전 페이지에서 여러분은 클래스를 만들고 new로 객체를 생성했습니다. 생성자는 그 new 호출 중에 실제로 실행되는 코드입니다. 그 유일한 목적은 바로 사용할 수 있는 객체를 돌려주는 것입니다. 즉, 필요한 모든 필드가 설정되어 있고, 절반만 초기화된 상태가 남지 않은 객체 말입니다.
생성자는 메서드처럼 보이지만 두 가지 차이가 있습니다. 클래스와 같은 이름을 가지며, 반환 타입이 없습니다. void조차 없습니다.
new Point(3, 4)는 객체를 할당한 다음 x = 3, y = 4로 생성자 본문을 실행합니다. new가 반환될 무렵이면 p는 완전히 초기화되어 있습니다.
this 키워드
위 생성자에서 매개변수의 이름은 x와 y로, 필드와 같습니다. this.x는 "이 객체에 속한 필드 x"를 의미하고, 그냥 x는 매개변수를 가리킵니다. this가 없으면 x = x는 매개변수를 자기 자신에게 할당할 뿐 필드는 건드리지 않은 채로 둡니다.
this가 필요한 경우는 매개변수가 필드를 가릴 때뿐이지만, 많은 사람이 명확성을 위해 어디서나 사용합니다. 흔한 실수는 이름이 충돌할 때 이를 잊는 것입니다. 코드는 컴파일되고 실행되지만, 필드를 기본값(null, 0, false)으로 조용히 내버려 둡니다.
기본 생성자
생성자를 전혀 작성하지 않으면 자바는 조용히 기본 생성자를 제공합니다. 이는 추가로 아무 일도 하지 않는, public이고 인수가 없는 생성자입니다. 그래서 생성자가 전혀 없는 클래스에서도 new가 동작했던 것입니다.
함정: 어떤 생성자든 작성하는 순간 공짜 생성자는 사라집니다.
class Box {
int size;
Box(int size) { // 이제 인수 없는 생성자가 없다
this.size = size;
}
}
new Box(); // 컴파일 오류: 생성자 Box()가 존재하지 않음
그래도 new Box()가 동작하기를 원한다면, 인수 없는 생성자를 직접 선언하세요.
생성자 오버로딩
클래스는 매개변수 목록이 서로 다르기만 하면 여러 개의 생성자를 가질 수 있습니다. 이는 메서드 오버로딩을 생성자에 적용한 것일 뿐입니다. 각 생성자는 객체를 만드는 서로 다른 방법을 제공합니다.
자바는 new에 전달하는 인수의 개수와 타입에 따라 일치하는 생성자를 선택합니다.
this()로 연쇄 호출하기
위의 중복에 주목하세요. 각 생성자가 직접 필드를 할당하고 있습니다. 한 생성자가 this(...)로 다른 생성자를 호출하게 하면 이를 피할 수 있습니다. 이 호출은 생성자 내의 첫 번째 문이어야 합니다.
이제 실제 초기화는 한곳에 있습니다. 더 작은 생성자들은 기본값을 채우고 작업을 전달하기만 합니다. 만약 this(...) 앞에 문을 놓으려 하면 컴파일러가 거부합니다.
생성자와 super()
모든 생성자는 먼저 암묵적으로 상위 클래스의 생성자를 호출합니다. 아무것도 작성하지 않으면 자바는 본문 맨 위에 숨겨진 super()(상위 클래스의 인수 없는 생성자)를 삽입합니다. 여러분은 서브클래스를 만들기 시작하면 이것을 직접 다루게 되며, 그것이 다음 주제입니다.
class Animal {
String name;
Animal(String name) { this.name = name; }
}
class Dog extends Animal {
Dog(String name) {
super(name); // 여기서는 부모 생성자를 명시적으로 호출해야 한다
}
}
Animal에는 인수 없는 생성자가 없기 때문에, Dog는 super(name)을 명시적으로 호출해야 합니다. 의지할 공짜 super()가 없는 것입니다. this()와 마찬가지로 super(...) 호출도 생성자 내의 첫 번째 문이어야 합니다.
다음: 상속
생성자는 단일 객체를 초기화하지만, super()는 이미 더 큰 무언가를 암시했습니다. 클래스는 다른 클래스를 기반으로 만들어질 수 있으며, 그 필드와 메서드, 생성자를 재사용할 수 있습니다. 한 클래스가 다른 클래스를 확장하는 그 관계가 바로 상속이며, 다음 페이지의 주제입니다.
자주 묻는 질문
자바에서 생성자란 무엇인가요?
생성자는 new로 객체를 만들 때 실행되는 특별한 메서드입니다. 클래스와 같은 이름을 가지며 반환 타입이 없습니다(void조차 없습니다). 그 역할은 새 객체를 유효한 초기 상태로 만드는 것으로, 보통 생성자의 인수를 객체의 필드에 할당함으로써 이루어집니다.
자바에서 생성자와 메서드의 차이는 무엇인가요?
생성자는 클래스와 정확히 같은 이름을 가지고 반환 타입을 선언하지 않으며, 객체가 생성될 때 new로만 호출할 수 있습니다. 일반 메서드는 자체 이름을 가지고 반환 타입(또는 void)을 선언하며, 이미 존재하는 객체에 대해 호출됩니다. 생성자는 초기화를 하고, 메서드는 그 후에 작업을 수행합니다.
자바에서 생성자를 작성하지 않으면 어떻게 되나요?
컴파일러가 인수가 없는 기본 생성자를 공짜로 제공합니다. 이 생성자는 매개변수를 받지 않으며 암묵적인 super() 호출 외에는 아무 일도 하지 않습니다. 하지만 어떤 생성자든 직접 작성하는 순간 이 공짜 생성자는 사라집니다. 따라서 매개변수 있는 생성자를 추가하면서도 여전히 new Thing()이 동작하기를 원한다면, 인수 없는 생성자를 명시적으로 선언해야 합니다.