最簡單的,是將構造器設置爲私有,再加入一個公有靜態方法,來獲得這個實例。
實現第二種方式就是運用靜態工廠的方式。優勢在於,它提供了靈活性:在不改變API的前提下,我們可以改變該類是否可以爲Singleton的想法。public class Elvis{ public static final Elvis INSTANCE = new Elvis(); private Elvis() { } // others methods }
但是這種方式存在缺陷型,如線程的不安全,反序列化時,也會生成新的實例。但線程的不安全可以通過synchronized關鍵字來解決,反序列化問題可以通過readResolve方法解決。public class Elvis{ private static final Elvis INSTANCE = new Elvis(); private Elvis() { } public static Elvis getINSTANCE() { return INSTANCE; } // others methods }
但這種方式存在一種致命的缺陷,在使用反射機制時,一樣的可以生成新的實例。public class Elvis implements Serializable{ private static final long serialVersionUID = 1L; private static final Elvis INSTANCE = new Elvis(); private Elvis() { } public static synchronized Elvis getINSTANCE() { return INSTANCE; } private Object readResolve(){ return INSTANCE; } // others methods }
運行結果返回falseElvis elvis=Elvis.getINSTANCE(); Class<Elvis> cls =Elvis.class; Constructor<Elvis> constructor = cls.getDeclaredConstructor(new Class[]{}); constructor.setAccessible(true); Elvis Anewelvis = constructor.newInstance(new Object[]{}); System.out.println(elvis==Anewelvis?"true":"false");
因此單例模式最好的方法時單元素的枚舉法。
public enum Elvis{ INSTANCE; private Elvis(){ } // others methods }
Singleton
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.