一、為什麼要學習列舉?
開發中有的時候我們是使用的資料或者物件是固定的幾個,比如:返回碼ErrorCode、四個季節等,這時候我們使用列舉類更合適。這裡就有人想到了,為什麼不用靜態常量來替代列舉類呢?
例如我們描述季節也可以使用常量:
public static final int
SPRING = 1;
public static final int
SUMMER = 2;
public static final int
FALL = 3;
public static final int
WINTER = 4;
相比於靜態的常量列舉類更加直觀,型別更加安全。
使用常量會有以下幾個缺陷:
1. 型別不安全
若一個方法中要求傳入季節這個引數,用常量的話,形參就是int型別,開發者傳入任意型別的int型別值就行,但是如果是列舉型別的話,就只能傳入列舉類中包含的物件。
2. 沒有名稱空間
開發者要在命名的時候以SEASON_開頭,這樣另外一個開發者再看這段程式碼的時候,才知道這四個常量分別代表季節。
二、列舉類的使用
列舉是JDK1。5新增的一個特性,它使用關鍵字
enum
來定義。
跟我們定義class不一樣的是,通常enum中的成員都是列舉類物件,並且預設省略了public static final定義,這也意味著我們使用列舉類的時候不需要建立列舉類物件直接呼叫即可。
列舉類的定義
下面我們先來定義一個簡單的列舉類看下跟之前定義class有什麼不同。
列舉類有以下幾個特點:
1。 enum和class、interface的地位一樣
2。 使用enum定義的列舉類預設繼承了java。lang。Enum,而不是繼承Object類,並且列舉類可以實現一個或多個介面。
3。 列舉類的所有例項都必須放在第一行展示,不需使用new 關鍵字,不需顯式呼叫構造器。自動新增public static final修飾。
4。 使用enum定義、非抽象的列舉類預設使用final修飾,不可以被繼承。
5。 列舉類的構造器只能是私有的。
列舉類內也可以定義屬性和方法,可以是靜態的和非靜態的。
實際上在第一行寫列舉類例項的時候,預設是呼叫了構造器的,所以此處需要傳入引數,因為沒有寫無參構造器,只能呼叫有引數的構造器。
列舉類的使用
列舉類通常是當做引數使用,Java5新增了enum關鍵字,同時擴充套件了switch,在switch。。。case結構中的case表示式中直接寫入列舉值,且不需加入列舉類作為限定。
使用如下:
我們發現當使用列舉當做引數或者限定型別的時候,不僅可以讓我們明確知道引數的型別保證了型別安全,也防止我們傳入錯誤的資料。
三、列舉類實現介面
列舉類可以實現一個或多個介面。與普通類一樣,實現介面的時候需要實現介面中定義的所有方法,若沒有完全實現,那這個列舉類就是抽象的,只是不需顯式加上abstract修飾,系統化會預設加上。
使用如下:
Operation列舉實際上是抽象的,不可以建立列舉值,所以此處在申明列舉值的時候,都重寫了抽象方法,這其實是匿名內部類的實現,花括號部分是一個類物件。
如果我們去看下編譯生產的class檔案,
我們發現共生成了五個class檔案,這樣就證明了PLUS,MINUS,TIMES,DIVIDE是Operation的匿名內部類的例項。