같은 클래스의 멤버들 간에 서로 호출할 수 있는 것처럼 아래 조건을 만족하면 생성자 간에도 서로 호출이 가능하다.
- 생성자의 이름으로 클래스 이름 대신 this를 사용한다.
- 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능하다.
아래 코드는 위의 두 조건을 만족시키지 못했기 때문에 에러가 발생한다.
class Car {
String color;
int door;
String gearType;
Car(String color) {
door = 5;
Car(color, "auto", 4);
}
}
에러가 발생한 이유.
- 생성자 내에서 다른 생성자를 호출할 때 this를 사용하지 않음.
- 두 번째 줄에서 생성자 호출.
this(color, "auto", 4)로 해야 한다.
생성자에서 다른 생성자를 첫 줄에서만 호출이 가능하도록 한 이유
생성자 내에서 초기화 작업 도중에 다른 생성자를 호출하게 되면, 호출된 다른 생성자 내에서 멤버 변수들의 값을 초기화할 것이므로 다른 생성자를 호출하기 이전의 초기화 작업이 무의미해질 수 있다.
// Case 1
Car() {
color = "white";
gearType = "auto";
door = 4;
}
// Case 2
Car() {
this("white", "auto", 4);
}
위 코드는 모두 같은 일을 하지만 Case 2처럼 this를 활용하면 더 간략히 표현할 수 있다.
같은 클래스 내의 생성자들은 일반적으로 서로 관계가 깊은 경우가 많아서 서로 호출하도록 하여 유기적으로 연결해주면 더 좋은 코드를 얻을 수 있다. 그리고 수정이 필요한 경우에도 보다 적은 코드만을 변경하면 되므로 유지보수가 쉬워진다.
// Case 1
Car(String c, String g, int d) {
color = c;
gearType = g;
door = d;
}
// Case 2
Car(String color, int door, String gearType) {
this.color = color;
this.door = door;
this.gearType = gearType;
}
Case 1 코드의 'color = c;'는 생성자의 매개변수로 선언된 지역 변수 c의 값을 인스턴스 변수 color에 저장한다. 이때 변수 color와 c는 이름만으로도 서로 구별되므로 아무런 문제가 없다.
하지만, Case 2 코드처럼 생성자의 매개변수로 선언된 변수의 이름이 color로 인스턴스 변수 color와 같을 경우에는 이름만으로 두 변수가 서로 구별이 안된다.
이런 경우에는 인스턴스 변수 앞에 'this'를 사용하면 된다.
이렇게 하면 this.color는 인스턴스 변수이고, color는 생성자의 매개변수로 정의된 지역 변수로 서로 구별이 가능하다.
생성자의 매개변수로 인스턴스 변수들의 초기값을 제공받는 경우가 많기 때문에 매개변수와 인스턴스 변수의 이름이 일치하는 경우가 자주 있다. 매개변수 이름을 다르게 하는 것보다 'this'를 사용해서 구별되도록 하는 것이 의미가 더 명확하고 이해하기 쉽다.
this, this()
this는 참조 변수로 인스턴스 자신을 가리킨다. 참조 변수를 통해 인스턴스의 멤버에 접근할 수 있는 것처럼, 'this'로 인스턴스 변수에 접근할 수 있는 것이다.
하지만, 'this'를 사용할 수 있는 것은 인스턴스 멤버뿐이다. static메서드(클래스 메서드)에서는 인스턴스 멤버들을 사용할 수 없는 것처럼, 'this' 역시 사용할 수 없다.
왜냐하면,
static 메서드는 인스턴스를 생성하지 않고도 호출될 수 있으므로 static메서드가 호출된 시점에 인스턴스가 존재하지 않을 수도 있기 때문이다.
this
인스턴스 자신을 가리키는 참조 변수, 인스턴스의 주소가 저장되어 있다.
모든 인스턴스 메서드에 지역 변수로 숨겨진 채로 존재한다.
this(), this(매개변수)
생성자, 같은 클래스의 다른 생성자를 호출할 때 사용한다.
this는 '참조 변수', this()는 '생성자'