본문 바로가기

study/effective java

[item4] 인스턴스화를 막기 위해서는 private 생성자를 사용해라.

모든 클래스가 객체로 만들어질 필요는 없다.

클래스가 객체로서 만들어져 사용되는 목적이 아니라 클래스 1개가 유틸리티들의 묶음으로서의 역할로 수행하는 경우가 있다. java 내장 클래스로는 Collections, Arrays , Math 등이 있다.

Math의 코드를 일부 발췌하면 다음과 같이 작성되어 있다.

public final class Math {

    /**
     * Don't let anyone instantiate this class.
     */
    private Math() {}
    // 생략....
}

private 생성자를 만들어놓고 주석으로 아무나 이 클래스를 인스턴스화하지 말라 고 경고도 해준다.

단순히 private 생성자를 만들어놓고 공란으로 만들 수도 있으나 문제가 있다. 외부가 아니면 내부에서 호출할 수도 있다. 유틸리티 메소드를 구현하다가 실수로 private 생성자를 만들고 이를 놓칠 수도 있다.

이를 막기 위해서는 단순히 비어있는 생성자를 사용하는 것이 아닌 예외를 던지는 것이다.

public class Math {
    private Math() {
        throw new AssertionError();
    }

    public static int max(int a, int b) {
        return a >= b ? a : b;
    }

    public static int min(int a, int b) {
        return a <= b ? a : b;
    }
}

위의 코드는 임의로 만든 Math 유틸리티 클래스로서 private 생성자를 호출하면 AssertionError를 던진다. 이를 통해 개발 과정에서 예외를 발생시켜서 문제를 파악하고 수정할 수 있도록 가이드를 줄 수 있다.

결론

원문 내용도 짧다보니 블로그 내용도 짧다. private 생성자를 통해 인스턴스화를 막는 것은 java를 배운 사람이라면 누구나 알 것이다. 이 책에서 말하고자한 내용은 private 생성자를 통해 인스턴스화를 막자가 아닌 모든 클래스가 객체로 존재할 필요는 없다 라는 것을 인지시켜 통찰력을 높이기 위함이다.


Reference