- new 연산자로 클래스로부터 객체를 생성할 때 호출되어 객체의 초기화를 담당
- 객체 초기화: 필드를 초기화하거나 메소드를 호출해서 객체를 사용할 준비를 하는 것
- 생성자를 실행하지 않고는 클래스로부터 객체를 만들 수 없음
- new 연산자에 의해 생성자가 성공적으로 실행되면
힙(heap)영역에 객체가 생성되고 객체의 번지가 리턴됨
- 모든 클래스는 생성자가 반드시 존재하며, 생성자를 하나 이상 가질 수 있음
- 클래스 내부에 생성자 선언을 생략했다면
컴파일러는 [public] 클래스() { } 기본 생성자를 바이트 코드에 자동 추가함
- 클래스가 public class로 선언되면 기본 생성자에도 public이 붙지만,
클래스가 public 없이 class로만 선언되면 기본 생성자에도 public이 붙지 않음
∴ 클래스에 생성자를 선언하지 않아도
new 연산자 뒤에 기본 생성자를 호출해서 객체를 생성할 수 있음
ex) Car myCar = new Car();
- 클래스에 명시적으로 선언한 생성자가 1개라도 있으면
컴파일러는 기본 생성자를 추가하지 않음
→ 명시적으로 생성자를 선언하는 이유는
객체를 다양한 값으로 초기화하기 위해서임
// 생성자 블록
클래스( 매개변수선언, ··· ) {
// 객체의 초기화 코드
}
- 리턴 타입이 없고 클래스 이름과 동일함
- 생성자 블록 내부에는 객체 초기화 코드가 작성됨
일반적으로 필드에 초기값을 저장하거나 메소드를 호출하여
객체 사용 전에 필요한 준비를함
- 매개 변수 선언은 생략할 수도 있고 여러 개를 선언해도 됨
Car myCar = new Car("그랜저", "검정", 300);
public class Car {
//생성자
Car(String model, String color, int maxSpeed) { ... }
}
→ 클래스에 생성자가 명시적으로 선언되어 있을 경우에는 반드시 선언된 생성자를 호출해서 객체를 생성해야만함
// Car클래스에 생성자 선언이 있기 때문에
// 기본 생성자(Car())를 호출해서 객체를 생성할 수 없고
// Car(String color, int cc)를 호출해서 객체를 생성해야함
class Car {
//생성자
Car(String color, int cc){
}
}
public class CarExample {
public static void main(String[] args {
Car myCar = new Car("검정", 3000);
//Car myCar = new Car(); <- 기본 생성자를 호출할 수 없음
}
}
- 클래스로부터 객체가 생성될 때 필드는 기본 초기값으로 자동 설정됨
- 필드를 선언할 때 초기값을 주게 되면
동일한 클래스로부터 생성되는 객체들은 모두 같은 값을 갖게 됨
- 초기화 하는 방법
1) 필드를 선언할 때 초기값을 주는 방법
2) 생성자에서 초기값을 주는 방법
→ 객체 생성 시점에 외부에서 제공되는 다양한 값들로 초기화되어야 한다면
생성자에서 초기화 해야함. 생성자의 매개값으로 이 값들을 받아 초기화해야함
👩💻생성자에서 필드 초기화 및 객체 생성 후 필드값 출력
class Korean{
//필드
String nation = "대한민국";
String name;
String ssn;
//생성자
public Korean(String n, String s) {
name = n;
ssn = s;
}
/*
* 필드와 매개 변수 이름이 동일하기 때문에 생성자 내부에서 해당 필드에 할 수 없음
* -> 동일한 이름의 매개 변수가 사용 우선순위가 높기 때문
* 해결방법
* 필드 앞에 'this.'를 붙이면 됨
* this는 객체 자신의 참조
* this라는 참조 변수로 필드를 사용하는 것과 동일함
*/
/*
* public Korean(String name, String ssn) {
* this.name(필드) = name(매개변수);
* this.ssn(필드) = ssn(매개변수);
* }
*/
}
public class KoreanExample {
public static void main(String[] args) {
Korean k1 = new Korean("박자바", "011225-1234567");
System.out.println("k1.name : " + k1.name);
System.out.println("k1.ssn : " + k1.ssn);
Korean k2 = new Korean("김자바", "930525-0654321");
System.out.println("k2.name : " + k2.name);
System.out.println("k2.ssn : " + k2.ssn);
}
}
💻결과
k1.name : 박자바
k1.ssn : 011225-1234567
k2.name : 김자바
k2.ssn : 930525-0654321
- 필드들을 모두 생성자에서 초기화한다면
생성자의 매개 변수 수는 객체의 필드 수만큼 선언되어야 함
- 보통은 중요한 몇 개의 필드만 매개 변수를 통해 초기화 되고,
나머지 필드들은 필드 선언 시에 초기화하거나
생성자 내부에서 임의의 값 또는 계산된 값으로 초기화함
아니면 객체 생성 후에 필드값을 별도로 저장하기도 함
- 매개 변수를 달리하는 생성자를 여러 개 선언하는 것
- 다양한 방법으로 객체를 생성할 수 있음
public class 클래스 {
// [생성자의 오버로딩] 매개 변수의 타입, 개수, 순서가 다르게 선언
클래스 ( [타입 매개변수, ···] ) {
...
}
클래스 ( [타입 매개변수, ···] ) {
...
}
}
ex)
▶ Car 클래스에서 생성자 오버로딩
public class Car {
Car() {...}
Car(String model) { ... }
Car(String model, String color) { ... }
Car(String model, String color, int maxSpeed) { ... }
}
▶ 객체 생성
Car car1 = new Car();
Car car2 = new Car("그랜저");
Car car3 = new Car("그랜저", "흰색");
Car car4 = new Car("그랜저", "흰색", 300);
* 주의할 점
: 매개 변수의 타입과 개수 그리고 선언된 순서가 똑같을 경우
매개 변수 이름만 바꾸는 것은 생성자 오버로딩이 아님
ex)
Car(String model, String color) { ... }
Car(String color, String model) { ... }
👩💻 생성자의 오버로딩 및 객체 생성 시 생성자 선택
class Car2{
//필드
String company = "현대자동차";
String model;
String color;
int maxSpeed;
//생성자
//생성자1
Car2(){
}
//생성자2
Car2(String model) {
this.model = model;
}
//생성자3
Car2(String model, String color){
this.model = model;
this.color = color;
}
//생성자4
Car2(String model, String color, int maxSpeed){
this.model = model;
this.color = color;
this.maxSpeed = maxSpeed;
}
}
public class CarExample2 {
public static void main(String[] args) {
//생성자1 선택
Car2 car1 = new Car2();
System.out.println("car1.company: " + car1.company);
System.out.println();
//생성자2 선택
Car2 car2 = new Car2("자가용");
System.out.println("car2.company: " + car2.company);
System.out.println("car2.model: " + car2.model);
System.out.println();
//생성자3 선택
Car2 car3 = new Car2("자가용", "빨강");
System.out.println("car3.company: " + car3.company);
System.out.println("car3.model: " + car3.model);
System.out.println("car3.color: " + car3.color);
System.out.println();
//생성자4 선택
Car2 car4 = new Car2("자가용", "빨강", 200);
System.out.println("car4.company: " + car4.company);
System.out.println("car4.model: " + car4.model);
System.out.println("car4.color: " + car4.color);
System.out.println("car4.maxSpeed: " + car4.maxSpeed);
System.out.println();
}
}
💻출력
car1.company: 현대자동차
car2.company: 현대자동차
car2.model: 자가용
car3.company: 현대자동차
car3.model: 자가용
car3.color: 빨강
car4.company: 현대자동차
car4.model: 자가용
car4.color: 빨강
car4.maxSpeed: 200
[표현법]
클래스( [매개변수, ···] ) {
this( 매개변수, ···, 값, ···); //클래스의 다른 생성자 호출
실행문;
}
- 생성자 오버로딩이 많아질 경우 생성자 간의 중복된 코드가 발생할 수 있음
→ 이 경우에는 필드 초기화 내용은 한 생성자에만 집중적으로 작성하고
나머지 생성자는 초기화 내용을 가지고 있는 생성자를 호출하는 방법으로 개선
- 자신의 다른 생성자를 호출하는 코드로 반드시 생성자의 첫 줄에서만 허용됨
- this()의 매개값은 호출되는 생성자의 매개 변수에 맞게 제공해야 함
👩💻 다른 생성자를 호출해서 중복 코드 줄이기 및 객체 생성 시 생성자 선택
class Car3{
//필드
String company = "현대자동차";
String model;
String color;
int maxSpeed;
//생성자
Car3(){
}
// this()를 사용해서 마지막 생성자인
// Car3(String model, String color, int maxSpeed)를 호출하도록 함
Car3(String model) {
this(model, "은색", 250);
}
Car3(String model, String color){
this(model, color, 250);
}
Car3(String model, String color, int maxSpeed){
// this(model, "은색", 250); 호출
// this(model, color, 250); 호출
this.model = model;
this.color = color;
this.maxSpeed = maxSpeed;
}
}
public class CarExample3 {
public static void main(String[] args) {
//생성자1 선택
Car3 car1 = new Car3();
System.out.println("car1.company: " + car1.company);
System.out.println();
//생성자2 선택
Car3 car2 = new Car3("자가용");
System.out.println("car2.company: " + car2.company);
System.out.println("car2.model: " + car2.model);
System.out.println();
//생성자3 선택
Car3 car3 = new Car3("자가용", "빨강");
System.out.println("car3.company: " + car3.company);
System.out.println("car3.model: " + car3.model);
System.out.println("car3.color: " + car3.color);
System.out.println();
//생성자4 선택
Car3 car4 = new Car3("자가용", "빨강", 200);
System.out.println("car4.company: " + car4.company);
System.out.println("car4.model: " + car4.model);
System.out.println("car4.color: " + car4.color);
System.out.println("car4.maxSpeed: " + car4.maxSpeed);
System.out.println();
}
}
💻출력
car1.company: 현대자동차
car2.company: 현대자동차
car2.model: 자가용
car3.company: 현대자동차
car3.model: 자가용
car3.color: 빨강
car4.company: 현대자동차
car4.model: 자가용
car4.color: 빨강
car4.maxSpeed: 200