가변인자가 선언된 메서드 호출마다 배열로 새로 생성 - 비효율적이므로 꼭 필요할 때만 사용
배열 타입 매개변수와 비교 - 배열 타입 매개변수는 반드시 인자를 지정해줘야함
가변인자를 사용할 때는 오버로딩을 사용하지 않는 것이 좋음
5. 생성자(constructor)
1) 생성자란
인스턴스 초기화 메서드
인스턴스 초기화는 인스턴스 변수들을 초기화한다는 의미
인스턴스가 생성될 때 호출
생성자의 조건
생성자의 이름이 클래스의 이름과 같음
리턴값이 없음 (void 생략 가능)
생성자의 실행순서
Card c = new Card(); - 연산자 new에 의해 메모리(heap)에 Card클래스의 인스턴스 생성 - 생성자 Card()가 수행됨 - Card인스턴스의 주소가 반환되어 참조변수 c에 저장
2) 기본 생성자 (default constructor)
기본 생성자
컴파일러가 제공하는 생성자
생성자를 정의하지 않고도 인스턴스 생성이 가능했던 이유
아래와 같은 기본 생성자를 추가하여 컴파일 - 클래스이름() { } ex. Card() { }
클래스의 '접근 제어자'가 public인 경우, 기본 생성자로 public 클래스이름() { }이 추가
기본 생성자가 추가되는 조건
정의된 생성자가 하나도 없을 때만 컴파일러가 추가
3) this
오버로딩된 생성자간의 호출 조건
클래스 이름 대신 this로 접근해야함
다른 생성자 호출시 반드시 첫 줄에서만 호출 가능 - 중간에 호출하면 초기화 작업이 무의미해질 수 있기 때문
지역변수와 구별을 위해 인스턴스 변수는 this로 접근
class Car{
String color;
String gearType;
int door;
Car(String color, String gearType, int door){
// 인스턴스 변수는 this로 접근
this.color = color;
this.gearType = gearType;
this.door = door;
}
Car(){
// 첫째줄
// this로 접근
this("white", "auto", 4);
}
}
this
인스턴스 자신을 가리키는 참조변수
참조변수를 통해 인스턴스에 접근하듯이, this로 인스턴스 변수에 접근
그러나 인스턴스멤버만 this 사용 가능
모든 인스턴스 메서드에 this가 지역변수로 숨겨진채 존재
4) 생성자를 이용한 인스턴스 복사
현재 사용중인 인스턴스와 같은 상태의 인스턴스 생성(복사)에 생성자 이용 가능
같은 클래스의 인스턴스 간의 차이는 인스턴스 변수 뿐이다
따라서, 인스턴스 변수를 복사해주면 두 인스턴스는 같은 상태가 된다
예제
class Car{
String color;
String gearType;
int door;
Car(String color, String gearType, int door){
this.color = color;
this.gearType = gearType;
this.door = door;
Car(Car c){
this(c.color, c.gearType, c.door);
}
}
// Car c1 = new Car("blue", "auto", 2);
// Car c2 = new Car(c1);
Object클래스에 정의된 clone메서드로 간단히 인스턴스를 복사할 수 있음
인스턴스 생성시 고려사항
어떤 클래스의 인스턴스를 생성할 것인지
어떤 생성자로 인스턴스를 생성할 것인지
6. 변수의 초기화
1) 대제목
초기화가 필요한 변수
멤버 변수 - 초기화하지 않으면 기본값으로 설정
지역 변수 - 반드시 사용전에 초기화해야함
멤버 변수의 초기화 방법
명시적 초기화(explicit initialization)
생성자(constructor)
초기화 블럭(initialization block)
명시적 초기화
변수 선언과 동시에 값을 초기화하는 것
지역 변수의 초기화 방법
초기화 블럭
복잡한 멤버변수 초기화에 사용
종류
클래스 초기화 블럭 - static { } - 클래스가 메모리에 처음 로딩될 때 한 번만 수행
인스턴스 초기화 블럭 - { } - 인스턴스 생성마다 수행
class InitBlock{
static { /* 클래스 초기화 블럭 */ }
{ /* 인스턴스 초기화 블럭 */ }
}
생성자 vs 인스턴스 초기화 블럭
인스턴스 변수의 초기화에는 생성자를 사용
모든 생성자에서 공통으로 수행되어야 하는 코드(중복 코드)는 인스턴스 초기화 블럭을 사용
코드의 중복을 제거하여, 재사용성을 높이고 신뢰성을 높여줌
// 생성자의 코드 중복
class Car{
static int count = 0;
int searialNo;
String color;
String gearType;
Car() {
// serialNo 저장 중복
count++;
this.searialNo = count;
this.color = "white"
this.gearType = "auto"
}
Car(String color, String gearType) {
// serialNo 저장 중복
count++;
this.serialNo = count;
this.color = color
this.gearType = gearType;
}
}
// 인스턴스 초기화 블럭을 이용한 중복 제거
class Car{
static int count = 0;
int searialNo;
String color;
String gearType;
{
count++;
serialNo = count;
}
Car() {
// serialNo 저장 중복
this.color = "white";
this.gearType = "auto";
}
Car(String color, String gearType) {
this.color = color;
this.gearType = gearType;
}
}
멤버변수 초기화 순서
클래스 변수의 초기화 - 클래스가 처음 로딩될 때 단 한 번 초기화됨 (JVM 종류에 따라, 클래스가 참조될 때 로딩되거나 프로그램 실행시 미리 로딩됨) - 따라서, 이미 메모리에 로딩된 클래스는 초기화가 다시 되지 않음 - 기본값 -> 명시적 초기화 -> 클래스 초기화 블럭