Singleton

最簡單的,是將構造器設置爲私有,再加入一個公有靜態方法,來獲得這個實例。

public class Elvis{
   public static final Elvis INSTANCE = new Elvis();

   private Elvis() {

   }
   // others methods
}
實現第二種方式就是運用靜態工廠的方式。優勢在於,它提供了靈活性:在不改變API的前提下,我們可以改變該類是否可以爲Singleton的想法。

public class Elvis{
   private static final Elvis INSTANCE = new Elvis();

   private Elvis() {

   }
   public static Elvis getINSTANCE() {
	return INSTANCE;
   }
   // others methods
}
但是這種方式存在缺陷型,如線程的不安全,反序列化時,也會生成新的實例。但線程的不安全可以通過synchronized關鍵字來解決,反序列化問題可以通過readResolve方法解決。

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
}
但這種方式存在一種致命的缺陷,在使用反射機制時,一樣的可以生成新的實例。
Elvis 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");
運行結果返回false


因此單例模式最好的方法時單元素的枚舉法。

public enum Elvis{
	INSTANCE;
	private Elvis(){

	}	
	// others methods
}



發佈了32 篇原創文章 · 獲贊 143 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章