天天看點

Java 枚舉類型

枚舉類型

  關鍵字enum可以将一組具名的值有限集合建立為一種新的類型,而這些具名的值可以作為正常的程式元件使用。

  ①values()方法傳回enum執行個體的數組,可以周遊enum執行個體

  ②ordinal()方法傳回一個int值,這是每個enum執行個體在聲明時的次序,從0開始

  ③getDeclaringClass()方法能夠知道其所屬的enum類

  ④name()方法傳回enum執行個體聲明時的名字

  ⑤valueOf()根據給定的名字傳回相應的enum執行個體

  ⑥Enum類實作了Comparable接口,具有compareTo()方法

  ⑦Enum類實作了Serializable接口

  ⑧通過static import可以靜态導入其他包中的enum執行個體,無需再用enum類型來修飾enum執行個體

  在添加新方法時,enum執行個體序列的最後添加一個分号,并且必須先定義執行個體。

Explore[compareTo, equals, getClass, getDeclaringClass, hashCode, name, notify, notifyAll, ordinal, toString, valueOf, values, wait]

Enum[compareTo, equals, getClass, getDeclaringClass, hashCode, name, notify, notifyAll, ordinal, toString, valueOf, wait]

  對比可知在Enum類中并沒有values()方法。通過反編譯,可以知道values()方法是由編譯器添加的static方法。同時也添加了valueOf()方法,該方法隻有一個參數,而在Enum類中的valueOf()方法需要兩個參數。

  将enum向上轉型為Enum就無法通路values()方法,但是在Class中有一個getEnumConstants()方法,通過該方法仍然可以取得所有enum執行個體。

  所有的enum都繼承自java.lang.Enum類。由于Java不支援多重繼承,是以enum不能再繼承其他,但是可以實作一個或多個接口。

  <T extends Enum<T>>表示T是enum執行個體。

  在一個接口内部,建立實作該接口的枚舉,以此将元素進行分組。這可以達到将枚舉元素分類組織的目的。

  當需要與一大堆類型打交道時,接口就不如enum好用了。為了建立一個“枚舉的枚舉”,可以建立一個新的enum,然後用其執行個體包裝原接口中的每一個enum類。

  EnumSet用于替代傳統的基于int的“位标志”,這種标志可以用來表示某種“開/關”資訊。對同一個參數重複地調用add()方法會被忽略掉。

  EnumMap是一種特殊的Map,它要求其中的鍵(key)必須來自一個enum。由于enum本身的限制,是以enumMap在内部可由數組實作。

  與EnumSet一樣,enum執行個體定義時的次序決定了其在EnumMap中的順序。enum的每個執行個體作為一個鍵,總是存在的。如果沒有用put()方法來存入相應值的話,其對應的值就是null。

(1)abstract方法

  要實作常量相關的方法,需要為enum定義一個或多個abstract方法,然後為每個enum執行個體實作該抽象方法。還可以覆寫常量相關的方法。

(2)使用enum的職責鍊

  在職責鍊設計模式中,程式員以多種不同的方式來解決一個問題,然後将它們連結在一起。當一個請求到來時,它周遊這個鍊,直到鍊中的某個解決方案能夠處理該請求。

src/com/my/chapter19/practice8.java · sumAll/Java程式設計思想 - 碼雲 - 開源中國 (gitee.com)

(3)使用enum的狀态機

  枚舉類型非常适合用來建立狀态機。一個狀态機可以具有有限個特定的狀态,它通常根據輸入,從一個狀态轉移到下一個狀态,不過也可能存在瞬時狀态,而一旦任務執行結束,狀态機就會立刻離開瞬時狀态。

  如果要執行的操作包含了不止一個類型未知的對象時,需要通過多路分發來解決。要利用多路分發,就必須為每一個類型提供一個實際的方法調用。

(1)使用enum分發

(2)使用常量相關的方法

  常量相關的方法允許我們為每個enum執行個體提供方法的不同實作,這可以解決多路分發。

(3)使用EnumMap分發

  使用EnumMap能夠實作“真正的”兩路分發。

(4)使用二維數組

  每個enum執行個體都有一個固定的值(基于其聲明的次序),并且可以通過ordinal()方法取得該值。是以我們可以使用二維數組,将競争者映射到競争結果。