November 10, 2021
무상태(stateless) 객체
나 설계상 유일해야 하는 시스템 컴포넌트
를 들 수 있다.// public static final 필드 방식의 싱글턴
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() { ... }
public void leaveTheBuilding() { ... }
}
Elvis.INSTANCE
를 초기화할 때 딱 한 번만 호출된다.AccessibleObject.setAccessible
을 사용해 private 생성자를 호출할 수 있다. -> 이러한 공격을 방어하려면 생성자를 수정하여 두 번째 객체가 생성되려 할 때 예외를 던지게 하면 된다.장점
public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis() { ... }
public static Elvis getInstance() { return INSTANCE; }
public void leaveTheBuilding() { ... }
}
Elvis.getInstance
는 항상 같은 객체의 참조를 반환하므로 제2의 Elvis 인스턴스란 결코 만들어지지 않는다.(리플렉션을 통한 예외는 똑같이 적용된다.)장점
정적 팩터리의 메서드 참조를 공급자(supplier)로 사용할 수 있다.
Elvis::getInstance
-> Supplier<Elvis>
둘 중 하나의 방식으로 만든 싱글턴 클래스를 직렬화하려면 단순히 Serializable을 구현한다고 선언하는 것만으로는 부족하다. -> 모든 인스턴스를 일시적(transient)이라고 선언하고 readResolve
메서드를 제공해야 한다. 이렇게 하지 않으면 직렬화된 인스턴스를 역직렬화할 때마다 새로운 인스턴스가 만들어진다.
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}