Java 利用列舉實現單例模式

高階java架構師發表於2018-09-30

Java列舉

基本用法

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

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

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

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

對於上面的例子,我們可以把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()來呼叫就可以了。
最後,對於某個例項而言,還可以實現自己的例項方法。再看下下面的程式碼:123456789101112131415161718
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;
 }
}1234567891011121314151617

這裡,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();
}123456789101112131415161718192021222324

列舉單例

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

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

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

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

可以看到,列舉也提供了序列化機制。某些情況,比如我們要透過網路傳輸一個資料庫連線的控制程式碼,會提供很多幫助。
最後借用 《Effective Java》一書中的話,

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

如果你想學好JAVA這門技術,也想在IT行業拿高薪,可以參加我們的訓練營課程,選擇最適合自己的課程學習,技術大牛親授,8個月後,進入名企拿高薪。我們的課程內容有:Java工程化、高效能及分散式、高效能、深入淺出。高架構。效能調優、Spring,MyBatis,Netty原始碼分析和大資料等多個知識點。如果你想拿高薪的,想學習的,想就業前景好的,想跟別人競爭能取得優勢的,想進阿里面試但擔心面試不過的,你都可以來,q群號為:180705916 進群免費領取學習資料。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31553506/viewspace-2215305/,如需轉載,請註明出處,否則將追究法律責任。

相關文章