정적 메서드와 정직 필드만을 담은 클래스를 만들고 싶을 때가 있다. 예를 들어 java.lang.Math, java.util.Arrays 처럼 기본 타입 값이나 배열 관련 메서드들을 모아 놓을 수 있다. 혹은 java.util.Collections처럼 특정 인터페이스를 구현하는 객체를 생성해주는 정적 메서드를 모아놓을 수 있다.
이렇나 유틸리티 클래스는 인스턴스 변수나 메서드가 없어도 사용할 수 있다. 하지만 사용자는 생성자가 자동 생성된 것인지 구분할 수 없다.
이를 막기 위해 추상 클래스로 만드는 경우가 있는데 추상 클래스로는 인스턴스화를 막을 수 없다. 하위 클래스를 만들어 인스턴스화 하면 그만이기 때문이다.
public abstract class Parents {
public static void talk(String message) {
System.out.println(message);
}
}
public class Child extends Parents {
public Student() {
super();
}
}
그렇기 때문에 유틸리티 클래스의 인스턴스화를 막기 위해서는 생성자의 접근 제어자를 private으로 만들어주어야 한다.
public abstract class Parents {
private Parents() {
throw new AssertionError();
}
public static void talk(String message) {
System.out.println(message);
}
}
명시적 생성자가 private이니 클래스 바깥에스는 접근할 수 없다. 이러한 private 생성자는 직관적이지 않기에 적절한 주석을 다는 것이 좋다. 또한 private으로 선언 하면서 하위 클래스가 상위 클래스의 생성자에 접근할 길이 막히기 때문에 상속을 불가능하게 하는 효과도 있다.