Java 利用枚舉實現單例模式


引言

單例模式比較常見的實現方法有懶漢模式,DCL模式公有靜態成員等,從Java 1.5版本起,單元素枚舉實現單例模式成為最佳的方法。


Java枚舉

基本用法

枚舉的用法比較多,本文主要旨在介紹利用枚舉實現單例模式的原理,所以這里也主要介紹一些相關的基礎內容。
首先,枚舉類似類,一個枚舉可以擁有成員變量,成員方法,構造方法。先來看枚舉最基本的用法:

enum Type{ A,B,C,D; }

 

創建enum時,編譯器會自動為我們生成一個繼承自java.lang.Enum的類,我們上面的enum可以簡單看作:

class Type extends Enum{ public static final Type A; public static final Type B; ... }

 

對於上面的例子,我們可以把Type看作一個類,而把A,B,C,D看作類的Type的實例。
當然,這個構建實例的過程不是我們做的,一個enum的構造方法限制是private的,也就是不允許我們調用。

“類”方法和“實例”方法

上面說到,我們可以把Type看作一個類,而把A,B。。。看作Type的一個實例。同樣,在enum中,我們可以定義類和實例的變量以及方法。看下面的代碼:

enum Type{ A,B,C,D; static int value; public static int getValue() { return value; } String type; public String getType() { return type; } } 在原有的基礎上,添加了類方法和實例方法。我們把Type看做一個類,那么enum中靜態的域和方法,都可以視作類方法。和我們調用普通的靜態方法一樣,這里調用類方法也是通過 Type.getValue()即可調用,訪問類屬性也是通過Type.value即可訪問。 下面的是實例方法,也就是每個實例才能調用的方法。那么實例是什么呢?沒錯,就是A,B,C,D。所以我們調用實例方法,也就通過 Type.A.getType()來調用就可以了。 最后,對於某個實例而言,還可以實現自己的實例方法。再看下下面的代碼: 

 

enum Type{
A{
    public String getType() {
        return "I will not tell you";
    }
},B,C,D;
static int value;

public static int getValue() {
    return value;
}

String type;
public String getType() {
    return type;
 }
}

這里,A實例后面的{…}就是屬於A的實例方法,可以通過覆蓋原本的方法,實現屬於自己的定制。
除此之外,我們還可以添加抽象方法在enum中,強制ABCD都實現各自的處理邏輯:

enum Type{ A{ public String getType() { return "A"; } },B { @Override public String getType() { return "B"; } },C { @Override public String getType() { return "C"; } },D { @Override public String getType() { return "D"; } }; public abstract String getType(); }

 

枚舉單例

有了上面的基礎,我們可以來看一下枚舉單例的實現方法:


public enum SomeThing { INSTANCE;  public String get(){
return "SomeThing";
} }


main(){
SomeThing someThing=SomeThing.INSTANCE;
someThing.get();
}

 

上面的類Resource是我們要應用單例模式的資源,具體可以表現為網絡連接,數據庫連接,線程池等等。
獲取資源的方式很簡單,只要 SomeThing.INSTANCE.getInstance() 即可獲得所要實例。下面我們來看看單例是如何被保證的:
首先,在枚舉中我們明確了構造方法限制為私有,在我們訪問枚舉實例時會執行構造方法,同時每個枚舉實例都是static final類型的,也就表明只能被實例化一次。在調用構造方法時,我們的單例被實例化。
也就是說,因為enum中的實例被保證只會被實例化一次,所以我們的INSTANCE也被保證實例化一次。
可以看到,枚舉實現單例還是比較簡單的,除此之外我們再來看一下Enum這個類的聲明:

public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable

 

可以看到,枚舉也提供了序列化機制。某些情況,比如我們要通過網絡傳輸一個數據庫連接的句柄,會提供很多幫助。
最后借用 《Effective Java》一書中的話,

單元素的枚舉類型已經成為實現Singleton的最佳方法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM