public class Singleton1 {
public static final Singleton1 INSTANCE = new Singleton1();
private Singleton1() {}
}
클라이언트에서는 아래처럼 인스턴스를 얻는데, private 생성자는 Singleton1.INSTANCE를 초기화할 때 딱 한 번만 호출되므로 싱글턴이 보장된다.
(private 이기 때문에 생성자를 호출할 수 없기 때문이다.)
단 리플렉션을 사용해 private 생성자를 호출하면 객체를 두 개 이상 만들 수 있는데 이에 대한 예외처리를 따로 해줘야한다(flag 변수를 둔다던지)
public class SingletonTest {
public static void main(String[] args) {
Singleton1 singleton1 = Singleton1.INSTANCE;
}
}
public Object readResolve(){
return INSTANCE;
해당 인스턴스는 항상 상수값이므로 재 생성할때마다 나머지는 가비지 컬렉터로 이동한다.
}
public class Singleton2 {
private static final Singleton2 INSTANCE = new Singleton2();
private Singleton2() {};
public static Singleton2 getInstance() {
return new Singleton2();
}
}
public class SingletonTest {
public static void main(String[] args) {
Singleton2 singleton2 = Singleton2.getInstance();
}
}
Supplier<Singleton2> instance = Singleton2::getInstance;
private static final transient Singleton2 INSTANCE = new Singleton2();
private Object readResolve() {
return INSTANCE;
}
public enum Singleton3 {
INSTANCE;
}
사실 그냥 스프링을 쓰면 된다. 빈으로 등록된 클래스는 해당 컨텍스트 내에서 싱글톤이 보장