Book/Effective Java

[Effective Java] 4.인스턴스화를 막으려거든 private 생성자를 사용하라

마닐라 2022. 6. 3. 23:02

단순히 정적 메서드와 정적 필드만을 담은 클래스를 만들고 싶을 때가 있을 것이다.

객체 지향적으로 사고하지 않는 이들이 종종 남용하는 방식이지만 나름의 쓰임새가 있다고한다.

 

정적 멤버만 담은 유틸리티 클래스는 인스턴스로 만들어 쓰라고 설계한 것이 아니다.

하지만 생성자를 명시하지 않으면 컴파일러가 자동으로 기본 생성자를 만들어준다.

사용자의 입장에서는 생성자가 자동 생성된 것인지 구분할 수 없다.

실제 공개된 API들 중에서도 이처럼 의도치 않게 인스턴스화할 수 있게 된 클래스가 종종 있다고 한다.

 

추상 클래스로 만드는 것은 인스턴스화를 막을 수 없다.

하위 클래스를 만들어서 그것을 인스턴스화할 수 있기 때문이다.

이를 본 사용자는 상속해서 쓰라는 뜻으로 오해할 수 있으니 더 큰 문제일 수 있다.

따라서 private 생성자를 추가하여 인스턴스화를 막아야한다.

 

// 코드 4-1 인스턴스를 만들 수 없는 유틸리티 클래스 (26~27쪽)
public class UtilityClass {
    // 기본 생성자가 만들어지는 것을 막는다(인스턴스화 방지용).
    private UtilityClass() {
        throw new AssertionError();
    }

    // 나머지 코드는 생략
}

 

생성자가 분명 존재하는데 호출할 수 없으므로 직관적이지 않다.

따라서 적절한 주석을 달아두는 것이 좋다고 한다.

이 방식은 자식에서 부모의 생성자를 호출할 수 없으므로 상속을 불가능하게 하는 효과도 있다.