정적 메서드와 정적 필드만을 담은 클래스를 만들고 싶을 때 사용된다.
생성자를 명시하지 않으면 컴파일러가 자동으로 기본생성자를 만들어주므로 private 생성자를 추가해 클래스의 인스턴스화를 막아야한다.
Math 클래스를 살펴보자
public final class Math {
/**
* Don't let anyone instantiate this class.
*/
private Math() {}
/**
* The {@code double} value that is closer than any other to
* <i>e</i>, the base of the natural logarithms.
*/
public static final double E = 2.7182818284590452354;
/**
* The {@code double} value that is closer than any other to
* <i>pi</i>, the ratio of the circumference of a circle to its
* diameter.
*/
public static final double PI = 3.14159265358979323846;
/**
* Constant by which to multiply an angular value in degrees to obtain an
* angular value in radians.
*/
private static final double DEGREES_TO_RADIANS = 0.017453292519943295;
/**
* Constant by which to multiply an angular value in radians to obtain an
* angular value in degrees.
*/
private static final double RADIANS_TO_DEGREES = 57.29577951308232;
/**
* Returns the trigonometric sine of an angle. Special cases:
* <ul><li>If the argument is NaN or an infinity, then the
* result is NaN.
* <li>If the argument is zero, then the result is a zero with the
* same sign as the argument.</ul>
*
* <p>The computed result must be within 1 ulp of the exact result.
* Results must be semi-monotonic.
*
* @param a an angle, in radians.
* @return the sine of the argument.
*/
@HotSpotIntrinsicCandidate
public static double sin(double a) {
return StrictMath.sin(a); // default impl. delegates to StrictMath
}
...
생성자를 private으로 명시해놓은 것을 알 수 있다. 만약 실수로 클래스 내에서 생성자가 호출되는 것을 막고 싶다면 아래와 같이 생성자내에서 예외가 터지도록 하면 된다.
private Math(){throw new AssertionError();}
하지만 이는 생성자가 존재하는데 호출할 수 없다는 뜻이므로 다른 사람이 보기에 직관적이지 못하다. 따라서 적절한 주석을 달아두는게 도움이 될 수 있다.
또한 이 방식은 상속을 불가능하게 할 수 있다. 모든 생성자는 명시적이든, 묵시적이든 상위 클래스의 생성자를 호출하게 되는데, 생성자가 private으로 선언되었으므로 하위 클래스가 상위 클래스에 접근하지 못해 상속하지 못하는 것이다.
이펙티브 자바 3/E