Effective Java 3/E
아이템4: 인스턴스화를 막으려거든 private 생성자를 사용하라
우리는 Java로 어떠한 프로젝트를 개발할 때에 정적 메서드만 담은 Util 클래스를 만들곤한다. 하지만 여태까지의 나는 Util 클래스의 생성자를 구현하지 않았다. Util 클래스의 생성자를 구현하지 않으면, 컴파일러는 자동으로 기본 생성자를 만든다. 이러한 경우에 의도치 않게 Util 클래스의 객체가 생성될 수 있게 된다. 그렇다면 Util 클래스의 객체를 생성할 수 없게 하려면 어떻게 해야할까? 우리는 그 답을 이미 알고 있다. 싱글톤 패턴에서 우리는 하나의 객체를 제외한 객체가 생성되지 않도록 private 생성자 함수를 만든다. 이처럼 JDK에 내장되어 있는 Arrays, Collections와 같은 Util 클래스에서도 마찬가지로 private 생성자 함수를 구현하여 객체가 생성되지 않도록 한다.
public class StringUtil {
// 기본 생성자가 생성되는 것을 막는다. (인스턴스화 방지용)
private StringUtil(){
throw new AssertionError();
}
...
}
생성자 함수의 접근제어자가 private로 설정되어 있어 외부 클래스에서는 접근할 수 없지만, 해당 클래스 내부에서 혹시라도 접근할 수 있어 AssertionError를 throw하고 있다. 생성자가 존재하지만 호출할 수 없다는 점에서 직관적이지는 않으니 해당 코드 앞부분에 주석을 달아놓자. 또한 이 방식은 상속을 불가능하게 하는 효과도 있다. 모든 생성자는 상위 클래스의 생성자를 호출하게 되는데, 그 생성자를 private 선언했으니 하위 클래스가 상위 클래스에 접근할 길이 막혀버린다. (There is no default constructor available in 'StringUtil' Compile Error 발생 )