Java 생성자 오버로딩과 this

생성자도 오버로딩처럼 여러개 정의할 수 있다.

MemberConstruct.java

public class MemberConstruct {
    String name;
    int age;
    int grade;

    MemberConstruct(String name, int age) {
        this.name = name;
        this.age = age;
        this.grade = 0;
    }
    
    MemberConstruct(String name, int age, int grade) {
        System.out.println("생성자 호출 name=" + name + ",age=" + age + ",grade=" + grade);
        this.name = name;
        this.age = age;
        this.grade = grade;
    }
}

MemberConstruct 클래스에는 기본 생성자 2개가 생겼다.

MemberContruct(String name, int age)
MemberContruct(String name, int age, int grade)

생성자 오버로딩 인자 2개를 줄 경우 grade 값을 0으로 설정하였다.

Main.java

public class Main {
    public static void main(String[] args) {
        MemberConstruct m1 = new MemberConstruct("guest1", 14, 90);
        MemberConstruct m2 = new MemberConstruct("guest2", 22);

        MemberConstruct[] members = { m1, m2 };

        for (MemberConstruct m : members) {
            System.out.println("이름: " + m.name + ", 나이: " + m.age + ", 점수:" + m.grade);
        }
    }
}

출력 예시

생성자 호출 name=guest1,age=14,grade=90
이름: guest1, 나이: 14, 점수:90
이름: guest2, 나이: 22, 점수:0

인자 값으로 "guest2", "22" 주어져도 생성자를 찾아가 점수 0으로 할당하도록 하였다. 즉, 시험을 치지 않은 학생은 0점으로 주어진 것이다.


this()

MemberConstruct 코드를 살펴보면 중복된 코드가 있다, "this.name", "this.age" 이 중복된 코드는 this() 를 응용하여 제거할 수 있다.

MemberConstruct.java

public class MemberConstruct {
    String name;
    int age;
    int grade;

    MemberConstruct(String name, int age) {
        this(name, age, 0);
        // this.name = name;
        // this.age = age;
        // this.grade = 0;
    }
    
    MemberConstruct(String name, int age, int grade) {
        System.out.println("생성자 호출 name=" + name + ",age=" + age + ",grade=" + grade);
        this.name = name;
        this.age = age;
        this.grade = grade;
    }
}

this() 로 간편하게 코드를 줄일 수 있는 이유는 자신의 클래스 MemberConstruct(String name, int age, int grade) 로 호출하기 때문이다.

MemberConstruct 객체를 생성하면 MemberConstruct(String name, int age) 호출하고 거기서 this(name, age, 0); 코드를 호출하면 MemberConstruct(String name, int age, int grade) 호출한다.


this() 메모리 주소 값 확인하기

this 는 자신의 참조 값을 가리키는 것을 확인할 수 있다.
간단한 코드로 this의 메모리 주소가 자신의 인스턴스 참조 값이라는 것을 확인할 수 있다.

MemberConstruct.java

public class MemberConstruct {
    String name;
    int age;
    int grade;

    MemberConstruct(String name, int age) {
        this(name, age, 0);
        System.out.println("MemberConstruct 클래스 this 호출" + this);
    }
    
    MemberConstruct(String name, int age, int grade) {
        System.out.println("생성자 호출 name=" + name + ",age=" + age + ",grade=" + grade);
        this.name = name;
        this.age = age;
        this.grade = grade;
    }
}

Main.java

public class Main {
    public static void main(String[] args) {
        MemberConstruct m2 = new MemberConstruct("guest2", 22);

        System.out.println("Main            클래스 호출: " + m2);
    }
}

출력 결과

생성자 호출 name=guest2,age=22,grade=0
MemberConstruct 클래스 this 호출: MemberConstruct@000001
Main            클래스 this 호출: MemberConstruct@000001

this 는 인스턴스 자신의 호출값이기 때문에 아래의 MemberConstruct(String name, int age, int grade) 생성자를 실행한다는 것을 다시 한번 확인할 수 있었다.

this() 를 사용하였을 때

MemberConstruct(String name, int age) -> MemberConstruct(String name, int age, int grade)

호출 결과도 생성자가 먼저 호출되어 println 문자열을 반환한다. 이후 this 를 선언한 곳에서도 문자열을 반환하고 이어서 Main 에서 문자열을 반환한다.

그리고 this() 를 사용한 경우 코드 첫 줄에만 적용된다!

this() 두번째 줄부터 호출한 경우 에러 발생

MemberConstruct(String name, int age) {
    System.out.println("MemberConstruct 클래스 this 호출" + this);
    this(name, age, 0); // 에러 발생
}