생성자는
new
연산자와 같이 사용되어 클래스로부터 객체를 생성할 때 호출되어 객체의 초기화를 담당한다.
Default Constructor
)자바의 모든 클래스는 하나 이상의 생성자가 반드시 필요하다.
만약 클래스 내부에 생성자 선언을 생략했다면 컴파일러가 기본 생성자를 바이트 코드에 자동으로 추가시킨다.
클래스이름() { }
public class
로 선언되면 기본 생성자에도 public
이 붙지만,public
없이 class
로만 선언되면 기본 생성자에도 public
이 붙지 않는다.Car() {}
기본 생성자 덕분에 클래스에 생성자를 선언하지 않아도 다음과 같이 new
연산자를 이용하여 객체를 생성할 수 있다.
Car myCar = new Car(); //기본 생성자
⭐ 클래스에 명시적으로 선언한 생성자가 하나라도 있다면, 컴파일러는 기본 생성자를 생성하지 않는다!
그러므로 만약 기본 생성자가 필요하다면 기본 생성자를 명시적으로 선언해주어야 한다.
클래스이름(매개변수선언, ... ) {
//객체의 초기화 코드
}
생성자는 리턴 타입이 없고, 클래스 이름과 동일하다.
public class Car {
//생성자
Car(String color, int cc) {
}
}
public class CarExample {
public static void main(String[] args) {
Car myCar = new Car("red", 3000);
//Car myCar = new Car(); <- 기본 생성자를 호출할 수 없다.
}
클래스로부터 객체가 생성될 때 필드는 기본 초기값으로 자동 설정된다.
만약 다른 값으로 초기화하고 싶다면
두 가지가 있다.
필드를 선언할 때 초기값을 주게 되면 동일한 클래스로부터 생성되는 객체들은 모두 (객체 생성 시점에는) 같은 데이터를 갖게 된다.
public class Korean {
String nation = "Korea";
String name;
int age;
}
위의 예제의 경우, Korean
객체의 nation
값은 모두 "Korea"
이다.
하지만 객체 생성 시점에 외부에서 제공되는 다양한 값들로 초기화되어야 한다면 생성자에서 초기화를 해야 한다.
위의 코드에서 name
과 age
필드값은 객체 생성 시점에 다양한 값을 가져야 하기 때문에 생성자의 매개값으로 값들을 받아 초기화해주어야 한다.
public class Korean {
//필드
String nation = "Korea";
String name;
int age;
//생성자
public Korean(String n, int a) {
name = n;
age = a;
}
}
보통 매개 변수의 이름은 필드 이름과 비슷하거나 동일한 이름을 사용한다.
그렇다고 다음과 같이 사용하면 안된다!
public Korean(String name, int age) {
name = name;
age = age;
}
필드와 매개 변수 이름이 동일할 때, 매개 변수가 사용 우선순위가 높기 때문에 생성자 내부에서 해당 필드에 접근할 수 없다!
그래서 다음과 같이 필드명 앞에 this.
를 붙여줘야 한다.
public Korean(String name, int age) {
this.name = name;
this.age = age;
}
Overloading
)자바에서는 다양한 방법으로 객체를 생성할 수 있도록 생성자 오버로딩을 제공한다.
생성자 오버로딩이란 매개 변수를 달리하는 생성자르 여러 개 선언하는 것을 말한다.
public class Person {
String name;
int age;
Person() {
}
Person(String name) {
this.name = name;
}
Person(String name, int age) {
this.name = name;
this.age = age;
}
}
생성자 오버로딩 시 주의할 점은 매개 변수의 타입과 개수, 그리고 선언된 순서가 똑같을 경우 매개 변수 이름만 바꾸는 것은 생성자 오버로딩이라고 할 수 없다!
Car(String model, String color) { ... }
Car(String color, String model) { ... } //오버로딩이 아니다!
생성자가 오버로딩되어 있을 경우,
new
연산자로 생성자를 호출할 때 제공되는 매개값의 타입과 수에 의해 호출된 생성자가 결정된다.
Car car1 = new Car(); //Car() (기본 생성자) 호출
Car car2 = new Car("그랜저"); //Car(String model) 생성자 호출
Car car3 = new Car("그랜저", "흰색"); //Car(String model, String color) 생성자 호출
Car car4 = new Car("그랜저", "흰색", 300); //Car(String model, String color, int maxSpeed) 생성자 호출
this()
)생성자 오버로딩이 많아질 경우, 생성자 간의 중복된 코드가 발생할 수 있다.
특히 매개 변수의 수만 달리하고 필드 초기화 내용이 비슷한 생성자일 때 많이 발생한다.
이 경우 필드 초기화 내용은 한 생성자에게만 집중적으로 작성하고
나머지 생성자는 초기화 내용을 가지고 있는 생성자를 호출하는 방법으로 개선할 수 있다.
생성자에서 다른 생성자를 호출할 때는
this()
코드를 사용한다.
this()
는 자신의 다른 생성자를 호출하는 코드로, 반드시 생성자의 첫 줄에서만 허용된다.this()
의 매개값은 호출되는 생성자의 매개 변수 타입에 맞게 제공해야 한다.this()
다음에는 추가적인 실행문들이 올 수 있다. 이 경우, 호출되는 생성자의 실행이 끝나면 원래 생성자로 돌아와서 다음 실행문을 진행한다.다음과 같이 this()
를 사용하여 중복 코드를 제거할 수 있다.