생성자 : 인스턴스가 생성될 때 호출되는 '인스턴스 초기화(인스턴스 변수들을 초기화) 메서드'이다.
- 생성자의 이름은 클래스의 이름과 같아야한다.
- 생성자는 리턴 값이 없다.
연산자 new가 인스턴스를 생성하는 것이지 생성자가 인스턴스를 생성하는 것이 아니다.
Card c = new Card();
- 연산자 new에 의해서 메모리(heap)에 Card클래스의 인스턴스가 생성된다.
- 생성자 Card()가 호출되어 수행된다.
- 연산자 new의 결과로, 생성된 Card인스턴스의 주소가 반환되어 참조변수 c에 저장된다.
기본 생성자(default constructor)
package object_oriented_programming;
class Date1{
int value;
}
class Date2 {
int value;
Date2(int x){ //매개변수가 있는 생성자
value = x;
}
}
public class ConstructorTest {
public static void main(String[] args) {
Date1 d1 = new Date1();
Date2 d2 = new Date2(); //compile오류
}
}
//결과
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
Date1 cannot be resolved to a type
Date1 cannot be resolved to a type
The constructor Date2() is undefined
at object_oriented_programming.ConstructorTest.main(ConstructorTest.java:18)
Date2에는 이미 생성자가 Date2(int x)가 정의되어 있으므로 기본 생성자가 추가되지않아 Date2 d2 = new Date2(10); 다음과 같이 정의가 되어야한다. 기본 생성자가 컴파일러에 의해서 추가되는 경우는 클래스에 정의된 생성자가 하나도 없을 때 뿐이다.
매개변수가 있는 생성자
package object_oriented_programming;
class Car{
String color;
String gearType;
int door;
Car(){}
Car(String c, String g, int d){
color =c;
gearType = g;
door = d;
}
}
public class CarTest {
public static void main(String[] args) {
Car c1 = new Car();
c1.color = "White";
c1.gearType = "auto";
c1.door = 4;
Car c2 = new Car("White", "auto", 4);
System.out.println("c1의 corlor = "+ c1.color + ", gearType="+c1.gearType+", door="+c1.door);
System.out.println("c2의 corlor = "+ c2.color + ", gearType="+c2.gearType+", door="+c2.door);
}
}
//결과
c1의 corlor = White, gearType=auto, door=4
c2의 corlor = White, gearType=auto, door=4
인스턴스를 생성한 다음에 인스턴스 변수의 값을 변경하는 것보다 매개변수를 갖는 생성자를 사용하는 것이 코드를 보다 간결하고 직관적으로 만든다.
생성자에서 다른 생성자 호출하기 - this(), this
- 생성자의 이름으로 클래스 이름 대신 this를 사용한다.
- 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능하다.
Car(String color) {
door = 5; //첫번째 줄
Car(color, "auto", 4); //에러. 생성자의 두 번째 줄에서 다른 생성자 호출
} //에러. this(color, "auto", 4);로 해야함
생성자 내에서 다른 생성자를 호출할 때는 클래스 이름인 'Car'대신 this를 사용해야하는데 그러지 않아서 발생하는 오류이며, 생성자 호출이 첫번 째 줄이 아니라 두 번째 줄이기 때문에 에러이다.
package object_oriented_programming;
class Car2{
String color;
String gearType;
int door;
Car2(){
this("white", "auto", 4);
}
Car2(String color){
this(color, "auto", 4);
}
Car2(String color, String gearType, int door){
this.color = color;
this.gearType = gearType;
this.door = door;
}
}
public class CarTest2 {
public static void main(String[] args) {
Car2 c1 = new Car2();
Car2 c2 = new Car2("blue");
System.out.println("c1의 corlor = "+ c1.color + ", gearType="+c1.gearType+", door="+c1.door);
System.out.println("c2의 corlor = "+ c2.color + ", gearType="+c2.gearType+", door="+c2.door);
}
}
//결과
c1의 corlor = white, gearType=auto, door=4
c2의 corlor = blue, gearType=auto, door=4
this는 참조변수로 인스턴스 자신을 가리킨다. 참조변수를 통해 인스턴스의 멤버에 접근할 수 있는 것처럼, 'this'로 인스턴스 변수에 접근할 수 있는 것이다. 하지만, static메서드(클래스 메서드)에서는 인스턴스 멤버들을 사용할 수 없는 것처럼 'this' 역시 사용할 수 없다. 왜냐하면 static메서드는 인스턴스를 생성하지 않고도 호출될 수 있으므로 static메서드가 호출된 시점에 인스턴스가 존재하지 않을 수도 있기 때문이다.
일반적으로 인스턴스 메서드는 특정 인스턴스와 관련된 작업을 하기 때문에 관련된 인스턴스의 정보가 필요하지만, static메서드는 인스턴스와 관련 없는 작업을 하므로 인스턴스에 대한 정보가 필요없기 때문이다.
- this 인스턴스 자신을 가리키는 참조변수, 인스턴스의 주소가 저장되어 있다.모든 인스턴스 메서드에 지역변수로 숨겨진채로 존재한다.
- this(), this(매개변수) 생성자, 같은 클래스의 다른 생성자를 호출할 때 사용한다.
출처 : JAVA의 정석 - (남궁성지음)