Java 利用枚舉實現單例模式

引言

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


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的,也就是不容許咱們調用。ide

「類」方法和「實例」方法

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

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的實例方法,能夠經過覆蓋本來的方法,實現屬於本身的定製。 blog

除此以外,咱們還能夠添加抽象方法在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();
}

枚舉單例

有了上面的基礎,咱們能夠來看一下枚舉單例的實現方法:資源

class Resource{
}

public enum SomeThing {
    INSTANCE;
    private Resource instance;
    SomeThing() {
        instance = new Resource();
    }
    public Resource getInstance() {
        return instance;
    }
}

  

 上面的類Resource是咱們要應用單例模式的資源,具體能夠表現爲網絡鏈接,數據庫鏈接,線程池等等。 get

獲取資源的方式很簡單,只要 SomeThing.INSTANCE.getInstance() 便可得到所要實例。下面咱們來看看單例是如何被保證的: 
首先,在枚舉中咱們明確了構造方法限制爲私有,在咱們訪問枚舉實例時會執行構造方法,同時每一個枚舉實例都是static final類型的,也就代表只能被實例化一次。在調用構造方法時,咱們的單例被實例化。 
也就是說,由於enum中的實例被保證只會被實例化一次,因此咱們的INSTANCE也被保證明例化一次。 
能夠看到,枚舉實現單例仍是比較簡單的,除此以外咱們再來看一下Enum這個類的聲明:

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

能夠看到,枚舉也提供了序列化機制。某些狀況,好比咱們要經過網絡傳輸一個數據庫鏈接的句柄,會提供不少幫助。 
最後借用 《Effective Java》一書中的話,

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

相關文章
相關標籤/搜索