[책리뷰/Effective Java] 객체 생성과 파괴

OCTOBER 04, 2020

아이템3) private 생성자나 열거 타입으로 싱글턴임을 보증하라

싱글턴(Singleton)

  • 인스턴스를 오직 하나만 생성할 수 있는 클래스
  • 함수와 같은 무상태(stateless) 객체나 설계상 유일해야 하는 시스템 컴포넌트에 사용

싱글턴을 만드는 방법 3가지

1. public static final 필드 방식

  • 예외: reflection API 인 AccessibleObject.setAccessible을 사용하여 private 생성자 호출 가능 이를 방어하기 위해 생성자를 수정하여 두번째 객체가 생성되려 할 떄 예외를 던지게 한다.
public class Elvis {
  public static final Elvis INSTANCE = new Elvis();
  private Elvis() {...}

  public void leaveTheBuilding() {...}
}

2. public static method 방식

public class Elvis {
  private static final Elvis INSTANCE;
  private Elvis() {...}
  public static getInstance() { return INSTANCE; }

  public void leaveTheBuilding() {...}
}

1,2번의 예외

  • 직렬화된 인스턴스를 역직렬화할 때마다 새로운 인스턴스가 생성
    — 두번째 객체가 생성될때 예외를 던져도?? 테스트 해보기
  • 이를 방지하기 위해 인스턴스 필드에 transient 키워드를 선언하고 readResolve 메서드를 생성한다.

    private/public static final transient Elvis INSTANCE;
    // 싱글턴임을 보장해주는 메서드, 역직렬화시 호출
    public Object readResolve() { return INSTANCE }; 
참고

3. Enum 방식

  • public 필드 방식과 비슷하지만 더 간결하고 위의 예외에 대한 방어가 다 된다.
  • 대부분 상황에서 원소가 하나뿐인 열거 타입이 싱글턴을 만드는 가장 좋은 방법이다.
  • 상속(extends) 이 필요한 경우 이 방법은 사용 할 수 없다. (implements 는 가능)
public enum Elvis {
   INSTANCE;
   public void leaveTheBuilding() {...}
}

작업 기록 블로그