ENUM 枚舉 使用 深度講解 一

JAVA枚舉類型(Enum)的使用

在現實社會中,有些類的實例對象是固定的。例如季節,只有春夏秋冬。例如月份,只有1-12個月,如果你創建了一個月份類,你當然有義務維護這個類的實例對象只能12個。這個時候就體現出枚舉類的作用了,java中枚舉類型就是針對這樣的場景需求所設計的。

語法(定義)

創建枚舉類型要使用 enum 關鍵字,隱含了所創建的類型都是 java.lang.Enum 類的子類(java.lang.Enum 是一個抽象類)。枚舉類型符合通用模式 Class Enum<E extends Enum<E>>,而 E 表示枚舉類型的名稱。枚舉類型的每一個值都將映射到 protected Enum(String name, int ordinal) 構造函數中,在這裏,每個值的名稱都被轉換成一個字符串,並且序數設置表示了此設置被創建的順序。

使用MonthEnum這個枚舉類的方法如下:

 

 

創建MonthEnum枚舉類,在使用的時候利用switch語句進行匹配從而得到相應的輸出值,這種做法很常見。如果只需要實現這樣的功能,定義一個常量類也可以實現。那麼就讓我們更進一步來看看枚舉類的作用,針對上面的例子,如果我們在很多場景下都要通過MonthEnum的實例對象獲取相對應的中文,每次都使用switch語句就顯得代碼冗餘。開發中,我們可以通過創建MonthEnum這個枚舉類時,讓MonthEnum中的每一個實例對象都有一個getChineseDesc()方法獲取中文描述。

 

枚舉類限制了此類的實例對象。當然,枚舉類可以有自己的成員變量和方法。上面的MonthEnum枚舉類有了chineseDesc這個成員變量,所以我們在定義實例對象時就要維護這個chineseDesc成員變量。此時調用簡化代碼如下:

 

 

還有另外一種方式:

 

 

就是先定義一個接口,接口中定義獲取的方法。然後又枚舉類生聲明實現接口,並由具體枚舉類對象實現方法。

示例如下:

基類接口

子實現類-枚舉類

注意枚舉中所有的枚舉實例必須均實現接口方法。

調用方式如下:

 

我們把枚舉類的所有實例對象,看做是一個集合,上面的switch可以看做是一種集合的遍歷方式,當對象集size很大時,遍歷很繁瑣,極端不適合開發。

所以有下面的遍歷方式如下:

遍歷的順序是枚舉的實例對象聲明的順序。

上面的枚舉對象中使用的values的方法,下面介紹枚舉中的方法:

int compareTo(E o) 
          比較此枚舉與指定對象的順序。

Class<E> getDeclaringClass()

返回與此枚舉常量的枚舉類型相對應的 Class 對象。

String name()

返回此枚舉常量的名稱,在其枚舉聲明中對其進行聲明。

int ordinal()

返回枚舉常量的序數(它在枚舉聲明中的位置,其中初始常量序數爲零)。

String toString()

返回枚舉常量的名稱,它包含在聲明中。

static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)

返回帶指定名稱的指定枚舉類型的枚舉常量。

 

給 enum 自定義屬性和方法

EnumSet,EnumMap 的應用

 

下面討論什麼場景使用枚舉類

當一個類的對象是存在且數量有限且固定的,這種情況下我們使用枚舉類就比較適當。

 枚舉類更加直觀,類型安全。使用常量會有以下幾個缺陷:

 

  1. 類型不安全。若一個方法中要求傳入季節這個參數,用常量的話,形參就是int類型,開發者傳入任意類型的int類型值就行,但是如果是枚舉類型的話,就只能傳入枚舉類中包含的對象。

2. 沒有命名空間。開發者要在命名的時候以SEASON_開頭,這樣另外一個開發者再看這段代碼的時候,才知道這四個常量分別代表季節。

三、枚舉類的語法及聲明注意事項

先看一個簡單的枚舉類。

1.enum和class、interface的地位一樣

2.使用enum定義的枚舉類默認繼承了java.lang.Enum,而不是繼承Object類。枚舉類可以實現一個或多個接口。

3.枚舉類的所有實例都必須放在第一行展示,不需使用new 關鍵字,不需顯式調用構造器。自動添加public static final修飾。

4.使用enum定義、非抽象的枚舉類默認使用final修飾,不可以被繼承。

5.枚舉類的構造器只能是私有的。

四.枚舉類介紹

枚舉類內也可以定義屬性和方法,可是是靜態的和非靜態的。

實際上在第一行寫枚舉類實例的時候,默認是調用了構造器的,所以此處需要傳入參數,因爲沒有顯式申明無參構造器,只能調用有參數的構造器。

構造器需定義成私有的,這樣就不能在別處申明此類的對象了。枚舉類通常應該設計成不可變類,它的Field不應該被改變,這樣會更安全,而且代碼更加簡潔。所以我們將Field用private final修飾。

 

五、枚舉類實現接口

枚舉類可以實現一個或多個接口。與普通類一樣,實現接口的時候需要實現接口中定義的所有方法,若沒有完全實現,那這個枚舉類就是抽象的,只是不需顯式加上abstract修飾,系統化會默認加上。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章