본문 바로가기

책리뷰/이펙티브자바

[이펙티브자바] 아이템4. 인스턴스화를 막으려면 private을 강제하라

728x90
반응형

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

예를 들면 java.lang.Math, java.util.Arrays와 같은 기본 타입의 값이나 배열 관련 메서드를 모아놓을 수 있다. 

java.util.Collections처럼 특정 인터페이스를 구현하는 객체를 생성해주는 정적 메서드를 모아놓을 수도 있다.

 

컴파일러는 생성자를 명시하지 않으면 public 생성자를 만들어준다. 

의도하지 않아도 인스턴스화할 수 있게 된다. 

 

public class UtilClass {

    public static String getName() {
        return "heypli";
    }

    public static void main(String[] args) {
        UtilClass utilClass = new UtilClass();

        UtilClass.getName();
    }
}

위 클래스의 의도는 UtilClass.getName();처럼 정적 메서드 사용을 의도했지만 인스턴스화가 가능해진다.

 

public abstract class UtilClass {

    public static String getName() {
        return "heypli";
    }

    class SubUtilClass extends UtilClass {
        
    }
    
}

abstract클래스로 만들면 인스턴스화가 불가능하지만 하위클래스를 만들어서 인스턴스화가 가능하다.

SubUtilClass utilClass = new SubUtilClass();

위와 같이 생성이 가능하다. 

(인스턴스를 생성할 수 있지만 하위클래스에서 상위클래스의 정적메서드나 필드를 사용할 수 없다.

그래서 abstract만 해도 괜찮지 않나..)

 

// util 클래스로 생성자 사용불가 
private UtilClass() {
    throw new AssertionError();
}

private생성자를 추가하면 클래스의 인스턴스화를 막을 수 있다.

AssertionError를 꼭 사용할 필요는 없지만 실수로라도 생성하지 않도록 막아준다. 

생성자가 존재하는데 호출하지 못하는 것이 직관적이지 않기 때문에 주석을 달아주는 게 좋다. 

 

728x90
반응형