생성자의 조건
1. 생성자의 이름은 클래스의 이름과 같아야 한다.
2. 생성자는 리턴값이 없다.
연산자 new가 인스턴스를 생성하는 것이지 생성자가 인스턴스를 생성하는 것이 아니다.
Card클래스의 인스턴스를 생성하는 과정
Card c = new Card();1.연산자 new에 의해서 메모리(heap)에 Card클래스의 인스턴스가 생성된다.
2. 생성자 Card()가 호출되어 수행된다.
3. 연산자 new의 결과로, 생성된 Card인스턴스의 주소가 반환되어 참조변수 c에 저장된다.
단, 기본 생성자가 컴파일러에 의해 추가되는 경우는 클래스에 정의된 생성자가 하나도 없을때 뿐이다.
//예제
class Car {
String color;
String gearType;
int door;
//매개변수가 없는 생성자
Car() {}
//매개변수가 있는 생성자
Car(String c, String g, int d) {
color = c;
gearType = g;
door = d;
}
}
단, 생성자간 호출에는 두가지 조건을 만족시켜야 한다.
- 생성자의 이름으로 클래스이름 대신 this를 사용한다.
- 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능하다.
아래는 위의 두가지 조건을 충족시키지 못한 오류코드의 예이다.
Car(String color) {
door = 5;
Car(color, "auto", 4); //에러1. 생성자의 두번째줄에서 다른 생성자를 호출
//에러2. this(color, "auto", 4);로 해야 한다.
}
아래와 같이
this.color는 인스턴스 변수이고,color는 생성자의 매개변수로 정의된 지역변수로 서로 구별이 가능하다.Car(String color, String gearType, int door) { this.color = color; this.gearType = gearType; this.door = door; }
this
this는 참조변수로 인스턴스 자신을 가리킨다. 참조변수를 통해 인스턴스의 멤버에 접근할 수 있는 것처럼this로 인스턴스 변수에 접근할 수 있는 것이다.this를 사용할 수 있는 것은 인스턴스멤버뿐으로static메서드(클래스 메서드)에서는 인스턴스 멤버들을 사용할 수 없는 것처럼'this'역시 사용불가하다.
- 왜냐하면static메서드는 인스턴스를 생성하지 않고도 호출될 수 있어서static메서드가 호출된 시점에 인스턴스가 존재하지 않을 수 있기 때문이다.- 생성자를 포함한 모든 인스턴스메서드에는 자신과 관련된 인스턴스를 가리키는 참조변수
'this'가 지역변수로 숨겨진채로 존재한다.
this
- 인스턴스 자신을 가리키는 참조변수, 인스턴스의 주소가 저장되어 있다.
- 모든 인스턴스메서드에 지역변수로 숨겨진채 존재한다.
this(), this(매개변수)- 생성자, 같은 클래스의 다른 생성자를 호출할때 사용한다.
참고this와this()는 비슷하게 생겼을뿐 완전히 다른 것이다.this는 '참조변수'이고,this()는 '생성자'이다.
Car(Car c) {
color = c.color;
gearType = c.gearType;
door = c.door;
}
인스턴스를 생성할때 결정해야 할 2가지 사항
1. 클래스 - 어떤 클래스의 인스턴스를 생성할 것인가?
2. 생성자 - 선택한 클래스의 어떤 생성자로 인스턴스를 생성할 것인가?
class InitTest {
int x; //인스턴스 변수
int y = x; //인스턴스 변수
void method1() {
int i; //지역변수
int j = i; // 에러. 지역변수를 초기화하지 않고 사용
}
}
멤버변수(클래스변수와 인스턴스변수)와 배열의 초기화는 선택적이지만 지역변수의 초기화는 필수적이다.
각 타입의 기본값(default value)은 아래와 같다.

멤버변수의 초기화 방법
1. 명시적 초기화 (explicit initialization)
2. 생성자 (constructor)
3. 초기화 블럭 (initialization block)
- 인스턴스 초기화 블럭 : 인스턴스 변수를 초기화하는데 사용.
- 클래스 초기화 블럭 : 클래스 변수를 초기화하는데 사용.
class Car {
int door = 4; // 기본형(primitive type) 변수의 초기화
Engine e = new Engine(); // 참조형(reference type) 변수의 초기화
}
초기화 블럭의 두가지 종류
- 클래스 초기화 블럭
클래스 변수의 복잡한 초기화에 사용된다.- 인스턴스 초기화 블럭
인스턴스변수의 복잡한 초기화에 사용된다.
class InitBlock {
static { /* 클래스 초기화 블럭입니다.
인스턴스 초기화 블럭앞에 단순히 static을 붙이면 된다.*/}
{/*인스턴스 초기화 블럭입니다.*/}
}
- 클래스변수의 초기화 시점
클래스가 처음 로딩될때 단 한번 초기화된다.- 인스턴스 변수의 초기화 시점
인스턴스가 생성될때마다 각 인스턴스별로 초기화된다.
- 클래스 변수의 초기화 순서
기본값 > 명시적 초기화 > 클래스 초기화 블럭- 인스턴스 변수의 초기화 순서
기본값 > 명시적 초기화 > 인스턴스 초기화 블럭 > 생성자
//예시
class InitTest {
static init cv = 1; // 명시적 초기화
int iv = 1; // 명시적 초기화
static { cv = 2; } // 클래스 초기화 블럭
{ iv = 2; } // 인스턴스 초기화 블럭
InitTest () { // 생성자
iv = 3;
}
}

클래스 변수는 인스턴스 블럭이 몇번 수행되는지와 관계없이 모든 인스턴스 블럭에 대해 같은 값을 갖는다.