스터디/이펙티브 자바 스터디

[이펙티브 자바] 아이템 4. 인스턴스화를 막으려거든 private 생성자를 사용하라

제이온 (Jayon) 2022. 4. 18.

effective-java에서 스터디를 진행하고 있습니다.

 

가끔 정적 메서드와 정적 필드만을 담은 클래스를 사용하면 유용할 때가 있다.

대표적으로, java.lang.Math, java.util.Arrays 와 같이 수학 연산이나 배열에 관련된 메서드들을 모아 놓는 유틸리티 클래스들을 사용할 수 있다. 혹은 java.util.Collections 와 같이 특정 인터페이스를 구현하는 객체를 생성해 주는 정적 팩터리 메서드를 모아 놓을 수도 있다.

 

이러한 유틸리티 클래스들은 따로 인스턴스 변수나 메소드가 없어도 사용할 수 있으므로 생성자가 필요하지 않다. 하지만, 생성자를 명시하지 않으면 컴파일러가 자동으로 public 기본 생성자를 만들어 준다. 그래서 사용자는 이 생성자가 자동으로 생성된 것인지 구분할 수가 없다.

 

이를 막기 위해 추상 클래스로 만드는 경우가 있는데, 추상 클래스로는 인스턴스화를 막을 수 없다. 하위 클래스를 만들어 인스턴스화하면 그만이기 때문이다.

 

public abstract class Person {

    public static void speak(String message) {
        System.out.println(message);
    }
}

public class Student extends Person {

    public Student() {
        super();
    }
}

 

그래서 유틸리티 클래스의 인스턴스화를 막기 위해서는 생성자의 접근 제어자를 private으로 만들어 주어야 한다.

 

public abstract class Person {

    private Person() {
        throw new AssertionError();
    }

    public static void speak(String message) {
        System.out.println(message);
    }
}

 

위와 같이 기본 생성자의 접근 제어자가 private이면 클래스 외부에서는 접근할 수 없다. 또한, 기본 생성자가 내부에서 호출될 경우 예외를 발생하도록 막아두었다.

 

이러한 private 생성자는 사용하는 입장에서 생성자를 이해하기 어려울 수 있으므로 주석을 달아주는 것도 좋다. 참고로 생성자를 private으로 막으면 상속을 불가능하게 하는 효과도 있다.

 

출처

댓글

추천 글