enum關鍵字是在Java1.5也就是Java SE5以後引入的一個新特性:它經過關鍵字enum來定義一個枚舉類,這個被定義的枚舉類繼承Enum類,這個枚舉類算是一種特殊類,它一樣能像其餘普通類同樣擁有構造器、方法,也可以實現接口,可是它不能再繼承其餘別的類,由於它的直接父類是Enum類,而且由於它默認的修飾符有final的存在,所以它沒法直接派生出其餘子類,除非將其使用abstract修飾。編程
按照《Java編程思想》中的原話來講:關鍵字enum能夠將一組具名的值的有限集合建立爲一種新的類型,而這些具名的值能夠做爲常規的程序組件來使用。多線程
在枚舉類出現以前Java是將常量放在接口或是放在普通類當中,而後使用public、static、final去修飾定義的常量,以下兩個例子:app
在枚舉類型出現以後,就可使用枚舉類型來定義常量,這些枚舉類型成員_一、_二、_3都默認被public、static、final修飾,語法以下:spa
可是Java枚舉類型輸出其常量的時候不像C /C++的枚舉那樣是數字,輸出的是其常量名,若是須要輸出其類型成員聲明時數字次序的話,須要調用ordinal()方法:線程
單例模式的特色有如下三個:code
- 一、單例類只能有一個實例。
- 二、單例類必須本身建立本身的惟一實例。
- 三、單例類必須給全部其餘對象提供這一實例。
咱們能夠發現枚舉類型十分契合以上三個特色,而且咱們經過建立枚舉類型,能夠發現它其中每個類型成員其實都是Singleton2這個枚舉類的一個實例。對象
public enum Singleton2 { SHERLOCK } class Main{ public static void main(String[] args) { Singleton2 sherlock = Singleton2.SHERLOCK; Singleton2 sherlock1 = Singleton2.SHERLOCK; System.out.println(sherlock == Singleton2.SHERLOCK); System.out.println(sherlock == sherlock1); System.out.println(Singleton2.SHERLOCK.getDeclaringClass()); } } 輸出結果: true true class com.sherlock.singleton.Singleton2
利用這個特性,咱們就能夠經過以下代碼建立單例,同時又由於這個特性,決定了它只能屬於餓漢式單例模式blog
public enum Singleton2 { SHERLOCK; public void print() { System.out.println("I am Sherlock!"); } } class Main{ public static void main(String[] args) { Singleton2 sherlock = Singleton2.SHERLOCK; System.out.println(Singleton2.SHERLOCK.getDeclaringClass()); sherlock.print(); } }
輸出結果以下: 繼承
優勢:接口
(1)可以避免多線程同步問題;
(2)可以防止反序列化從新建立對象;
(3)實現比起其它懶漢式、餓漢式單例來講十分簡潔,閱讀性好;
缺點:
(1)由於是餓漢式加載,因此會致使枚舉實例會長期存在於內存當中;