1. 程式人生 > >Effective Java 建立和銷燬物件 3.用私用構造器或者列舉型別強化Singleton屬性

Effective Java 建立和銷燬物件 3.用私用構造器或者列舉型別強化Singleton屬性

Singleton 也就是常說的單例模式,只能被例項化一次,當然這看操作。


java1.5版本之前,實現Singleton有兩種方法。這兩種方法都要把構造器保持為私有的,並匯出公有的靜態成員,一遍允許客戶端能夠訪問該類的唯一例項。在第一種方法中,公有靜態成員是個final域:
public class Elvis{
    public static final Elvis INSTANCE = new Elvis();
    private Elvis(){...}
    public void leaveTheBuilding(){...}
}


私有構造器僅被呼叫一次,用來例項化共有的靜態final域Elvis.INSTANCE。


在實現Singleton的第二種方法中,共有的成員是個靜態工廠方法:


public class Elvis{
    public static final Elvis INSTANCE = new Elvis();
    private Elvis(){...}
    public static Elvis getInstance(){return INSTANCE}
    public void leaveTheBuilding(){...}
}
對於靜態方法Elvis.getInstance的所有呼叫,都會返回同一個物件引用,所以,永遠不會建立其他的Elvis例項。 
公有域的主要好處在於,組成類的成員的宣告很清楚的表明了這個類是一個Singleton:公有的靜態與是final的,所以該域將總是包含相同的物件引用。 
在java1.5版本起,實現Singleton還有第三種方法。只需要編寫一個包含單元素的列舉型別:


public enum Elvis(){
    INSTANCE;
    public void leaveBuilding(){...}
}
這種方法在功能上與公有域方法相近,但是它更加簡潔,無償的提供了序列化機制,絕對防止多次例項化,即使是在面對複雜的序列化或者反射攻擊的時候,雖然這種方法還沒有廣泛採用,但是單元素的列舉型別已經成為Singleton的最佳方法。