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

뚝딱이·2024년 1월 7일
0

이펙티브 자바

목록 보기
5/55
post-thumbnail

정적 메서드와 정적 필드만을 담은 클래스를 만들고 싶을 때 사용된다.

  • java.lang.Math, java.util.Array 처럼 기본 타입 값이나 배열 관련 메서드들을 모아놓을 수 있다.
  • 특정 인터페이스를 구현하는 객체를 생성해주는 정적 메서드를 모아놓을 수도 있다.
  • final 클래스와 관련한 메서드들을 모아놓을 때도 사용한다.

생성자를 명시하지 않으면 컴파일러가 자동으로 기본생성자를 만들어주므로 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

profile
백엔드 개발자 지망생

0개의 댓글

관련 채용 정보