1. 생성자란?
- 인스턴스가 생성될 때마다 호출되는 인스턴스 초기화 메서드
- 즉, 생성자는 인스턴스가 생성될 때 필드를 초기화하기 위한 것이다
- 생성자는 특별한 메서드로서 일반 메서드와 다음과 같은 차이를 지닌다
- 인스턴스 생성 시 자동으로 호출된다
- 반환값이 없으므로 리턴 타입을 명시하지 않는다
- 클래스 이름과 같기 때문에 일반 메서드와 다르게 대문자로 시작한다
2. 생성자의 특징
- 형태: 메서드 형태
- 리턴 타입: 리턴 타입을 선언하지 않는다
- 이름: 소속된 클래스 이름과 같다
- 역할: 필드의 초기화를 담당한다
- 호출 시기: 인스턴스 생성 시 자동으로 호출된다
// 생성자 선언
접근제한자 클래스명(매개변수) {
실행문;
}
// 예시
public Member(String name, int age) {
this.name = name;
this.age = age;
}
3. 생성자 오버로딩
- 일반 메서드를 선언할 때 같은 기능을 하지만 인자값을 다양하게 받아 처리하고 싶을 때는 같은 이름으로 메서드를 여러 개 선언할 수 있다
- 마찬가지로 생성자도 오버로딩이 가능하고, 이를 생성자 오버로딩이라고 한다
// 매개변수가 없는 생성자를 기본 생성자(default constructor)라고 한다.
public Member() {
}
public Member(String name) {
this.name = name;
}
public Member(String name, int age) {
this.name = name;
this.age = age;
}
new Member() // 참조 타입 필드인 name은 null, 기본 타입 필드인 age은 0으로 초기화된다.
new Member("Amy") // 기본 타입 필드인 age은 0으로 초기화된다.
new Member("Amy", 23)
4. 기본 생성자
- 생성자 중에서 다음 생성자처럼 매개변수가 없는 생성자를 기본 생성자(default constructor)라고 한다
- 별도의 생성자 선언이 없으면 컴파일러는 자동으로 생성자를 추가해준다
- 만일 하나 이상의 생성자가 선언되어 있다면 컴파일러는 기본 생성자를 추가하지 않는다
// Nonmember.java
public class Nonmember {
}
// Decompiled Nonmember.class file
public class Nonmember {
public Nonmember() {
}
}
5. this 키워드
- this 키워드는 자바에서 사용하는 예약어로 현재 실행 중인 인스턴스의 주솟값을 나타낸다
- 쉽게 생각해서 this는 this가 사용된 곳, 즉 자신의 주솟값이라고 할 수 있다
- 따라서 this는 사용한 곳에 따라 값이 달라진다
- 일반적으로 this는 다음과 같은 용도로 사용된다
- 인스턴스의 멤버를 가리킬 때
- 생성자를 호출할 때
- 자신의 주솟값을 전달하고 싶을 때
- 생성자는 기본적으로 new 명령문을 이용해 객체를 생성할 때 자동으로 호출되지만, 생성자 내에서 다른 생성자를 호출할 수도 있다
- 즉, 생성자는 명시적으로 호출할 수 있는데, 이는 생성자 내에서만 가능하다
- 이때 예약어 this()가 사용된다
6. this()를 활용한 생성자 호출
1) AS-IS
public class Member {
private String name;
private int age;
public Member() {
this.name = "guest";
this.age = 0;
}
public Member(String name) {
this.name = name;
this.age = 0;
}
public Member(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Member m1 = new Member();
Member m2 = new Member("Amy");
Member m3 = new Member("Amy", 23);
}
}
2) TO-BE
public class Member {
private String name;
private int age;
public Member() {
this("guest");
}
public Member(String name) {
this(name, 0);
}
public Member(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Member m1 = new Member();
Member m2 = new Member("Amy");
Member m3 = new Member("Amy", 23);
}
}
- this()문을 사용하면 위와 같이 중복된 코드를 제거할 수 있다
- main() 메서드에서 new Member() 명령문으로 실행되는 생성자의 순서는 다음과 같다
- 생성자 호출문 this()는 생성자 내에서만 사용할 수 있고, 생성자 내에서 가장 첫 번째 줄에 위치해야 한다
public Member() {
this.age = 0;
this("guest"); // 에러 발생
}
7. super 키워드
- super 키워드는 자바의 예약어로 상속 관계에서 부모 클래스를 나타낸다
- 즉, 자식 클래스에서 부모 클래스의 멤버에 직접 접근하려고 할 때 사용할 수 있다
- super는 this와 비슷하다
- this는 현재 자신의 인스턴스를 참조하는 변수이고, super는 부모 인스턴스를 참조하는 변수다
- 따라서 this, super 모두 사용하는 위치에 따라 값이 달라진다
8. super()를 이용한 부모 생성자 호출
- 아래와 같이 super()를 이용하여 부모 생성자를 호출할 수 있다
public class Fruit {
private String name;
public Fruit() {
this.name = "fruit";
}
public Fruit(String name) {
this.name = name;
}
}
public class Apple extends Fruit {
private BigDecimal price;
public Apple(BigDecimal price) {
super("apple");
this.price = price;
}
}
- 클래스에 생성자가 하나도 선언되어 있지 않으면 컴파일러가 본문이 비어있는 기본 생성자를 자동으로 추가한다
- 이와 유사하게 임의의 클래스를 상속받은 클래스는 컴파일러가 컴파일 타임에 super()를 자동으로 추가한다
- super()문은 상속받은 클래스의 모든 생성자 첫 번째 줄에 자동으로 추가된다
- 단, 생성자 내에 super() 문을 사용하지 않았을 때만 자동으로 추가된다
public class Apple extends Fruit {
private BigDecimal price;
public Apple(BigDecimal price) {
super(); // super()를 직접 호출하지 않은 경우 컴파일러가 자동으로 추가
this.price = price;
}
}
- this()가 생성자 내에서 다른 생성자를 호출할 때 사용되듯이, super()도 마찬가지로 생성자 내에서만 사용이 가능하다
- 단, 자신이 아닌 부모 생성자를 호출할 때 사용한다
9. 생성자 정리
1. 모든 클래스는 생성자가 반드시 존재한다
- 단, 개발자가 명시하지 않으면 컴파일러가 내용이 비어 있는 기본 생성자를 생성한다
2. 자식 클래스의 모든 생성자에는 첫 번째 줄에 super()문이 자동으로 추가된다
- 단, 생성자에서 super()문을 사용하지 않았을 때만 자동으로 추가된다
3. 따라서 자식 클래스의 인스턴스를 생성할 때 부모 클래스의 생성자도 함께 호출된다
- 따라서 자식 클래스의 인스턴스를 생성할 때 부모 클래스의 생성자도 함께 호출된다
10. 참고
- 자바의 정석 (남궁성 저)
- 처음해보는 자바 프로그래밍 (오정임 저)
'프로그래밍 언어 > Java + Kotlin' 카테고리의 다른 글
[Java] 제네릭 타입 소거(Generic Type Erasure)에 대해 알아보자 (0) | 2023.08.02 |
---|---|
[Java] Collection과 Collections의 차이 (0) | 2023.03.16 |
[Kotlin] 코틀린에서 애너테이션 사용하기 (vs 자바) (0) | 2022.12.19 |
[Java] JVM을 통해 알아보는 자바 프로그램 실행방식 (0) | 2022.12.15 |
[Kotlin] BigDecimal을 비교할 때 주의하라 (0) | 2022.11.08 |