실글톤 패턴 알아야 할 것
실글톤 패턴 실무에서 사용시,
public class Sesstings {
private static Settings instance;
private Settings() {};
public static Settings getInstance() {
if(instance == null){
instance = new Settings();
}
return instance;
}
}
public class Sesstings {
private static Settings instance;
private Settings() {};
public static sychronized Settings getInstance() {
if(instance == null){
instance = new Settings();
}
return instance;
}
}
public class Sesstings {
private static final Settings INSTANCE= new Setiings();
private Settings() {};
public static Settings getInstance() {
return INSTANCE;
}
}
public class Sesstings {
private static volatile Settings instance;
private Settings() {};
public static Settings getInstance() {
if(instance == null) {
sychronized (Settings.class) {
if(instance == null){
instance = new Settings();
}
}
}
return instance;
}
}
public class Sesstings {
private Settings() {};
private static class SettingsMolder{
private static final Settings INSTANCE = new Settings();
}
public static Settings getInstance() {
return SettingsMolder.INSTANCE;
}
}
public class App{
public static void main(String[] args) throws NosuchMethodException, InvocationTargerException, InstanceException{
Settings settings = Settings.getInstance();
Constructor<Settings> constructor = Settings.class.getDeclaredConstructor();
constructor.setAccessible(true);
Settings settings1 = constructor.newInstance();
System.out.println(settings == settings1);
}
}
//먼저 settings에 implements Serializable 을 선언해주고 시작해야한다.
public class App{
public static void main(String[] args) throws NosuchMethodException, InvocationTargerException, InstanceException{
Settings settings = Settings.getInstance();
try(ObjectOutput out = new ObjectOutputStream(new FileOutputStream("settings.obj"))) {
out.writeObject(settings);
}
try(ObjectInput in = new ObjectInputStream(new FileInputStream("settings.obj"))) {
settings1 = (Settings)in.readObject();
}
System.out.println(settings == settings1);
}
}
protected Object readResolve() {
return getInstance();
}
Settings에서 readResolve()를 통해서 getInstance() 메소드를 호출하게 하는 방법이다.
이렇게 작성하면 역직렬화 상황 시 getInstance()가 호출되게 돼서 해결된다.
근데 리플렉션은 대응이 안되기 때문에 enum을 쓰면 된다.
public enum Settings {
INSTANCE;
private Integer number;
public Integer getNumber(){
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
}
Settings.getInstance();
를 Settings.INSTANCE
로 바꾸면 된다.