1. 枚舉類定義html
在某些狀況下,一個類的對象是有限並且固定的,好比季節類,它只有4個對象,這種實例有限並且固定的類,在Java裏被稱爲枚舉類。java
2. 早期實現枚舉的方式程序員
public static final int SEASON_SPRING = 1; public static final int SEASON_SUMMER= 2; public static final int SEASON_FALL = 3; public static final int SEASON_WINTER = 4;
這種定義季節的方式簡單明瞭,但存在以下幾個問題:api
1)類型不安全:由於上面的每一個季節其實是一個int整數,所以徹底能夠把一個季節當成一個int整數使用,例如進行加法運算SEASON_SPRING+SEASON_SUMMER,這種代碼徹底正常。安全
2)沒有命名空間:當須要使用季節時,必須在SPRING前使用SEASON_前綴,不然程序可能與其它類中的靜態常量混淆。微信
3)打印輸出的意義不明確:當輸出某個季節時,例如輸出SEASON_SPRING,實際上輸出的是1,這個1很難猜想出它是表明春天的。數據結構
但枚舉又確實存在的意義,所以早期也可採用經過定義類的方式來實現,能夠採用以下設計方式。測試
1)經過private將構造器隱藏起來。spa
2)把這個類的全部可能實例都使用public static final修飾的類變量來保存。.net
3)若是有必要,能夠提供一些靜態方法,容許其餘程序根據特定參數來獲取與之匹配的實例。
4)使用枚舉類可使程序更加健壯,避免建立對象的隨意性。
但經過定義類來實現枚舉的代碼量比較大,實現起來比較麻煩,Java從JDK1.5後就增長了對枚舉類的支持。
3. 枚舉類詳解
Java5新增了一個enum關鍵字(它與class、interface關鍵字的地位相同),用以定義枚舉類。正如前面看到的,枚舉類是一個特殊的類,它同樣能夠有本身的成員變量、方法,能夠實現一個或者多個接口,也能夠定義本身的構造器。一個Java源文件中最多隻能定義一個public訪問權限的枚舉類,且該Java源文件也必須和該枚舉類的類名相同。
但枚舉類終究不是普通的類,它與普通類有以下區別:
1)枚舉類不能顯示繼承其它類,枚舉類能夠實現一個或多個接口,使用enum定義的枚舉類默認繼承了java.lang.Enum類,而不是默認繼承Object類。其中Enum類實現了Serializable和Comparable兩個接口。
2)枚舉類不能派生子類,使用enum定義、非抽象的枚舉類默認會使用final修飾。
3)枚舉類的構造器只能使用private訪問控制符,若是省略了構造器的訪問控制符,則默認使用private修飾。
4)枚舉類的實例必須在枚舉類的第一行顯示列出,不然這個枚舉類永遠都不能產生實例。列出這些實例時,系統會自動添加public static final修飾,無需程序員顯示添加。
枚舉類默認提供了一個values()方法,該方法能夠很方便的遍歷全部枚舉值。
下面程序定義了一個SeasonEnum枚舉類
public enum SeaonEnum{ //在第一行列出4個枚舉實例 SPRING,SUMMER,FALL,WINTER; }
定義枚舉類時必須顯示的列出全部的枚舉值,枚舉值之間使用英文逗號隔開,以英文分號結束。
若是須要使用該枚舉類的某個實例,則可使用類名.變量名的形式,如SeaonEnum.SPRING。
看下面程序實例:
public class EnumTest{ public void judge(SeasonEnum s) //switch語句裏的表達式能夠是枚舉值 switch(s){ case SPRING: System.out.println("春暖花開,正好踏青"); break; case SUMMER: System.out.println("夏日炎炎,適合游泳"); break; case FALL: System.out.println("秋高氣爽,及時進補"); break; case WINTER: System.out.println("冬日飄雪,圍爐賞雪"); break; } } public static void main(String[] args){ //枚舉類默認有一個values()方法,返回該枚舉類的全部實例 for(SeasonEnum s : SeasonEnum.values()){ System.out.println(s); } //使用枚舉實例時,可經過EnumClass.variable形式來訪問 new EnumTest().judge(SeasonEnum.SPRING); }
}
上面程序測試了SeasonEnum枚舉類的用法,該類經過values()方法返回了SeasonEnum枚舉類的全部實例,並經過循環迭代輸出了SeasonEnum枚舉類的全部實例。
因爲全部的枚舉類都繼承了java.lang.Enum類,因此枚舉類能夠直接使用java.lang.Enum類中所包含的方法。java.lang.Enum類中提供了以下幾個方法。
1)int compareTo(E o):比較此枚舉與指定對象的順序。在該對象小於、等於或大於指定對象時,分別返回負整數、零或正整數。 枚舉常量只能與相同枚舉類型的其餘枚舉常量進行比較。該方法實現的天然順序就是聲明常量的順序。
2)String name():返回此枚舉常量的名稱,在其枚舉聲明中對其進行聲明。 與此方法相比,大多數程序員應該優先考慮使用toString()方法,由於 toString 方法返回更加用戶友好的名稱。該方法主要設計用於特殊情形,其正確性取決於獲取正確的名稱,其名稱不會隨版本的改變而改變。
3) int ordinal():返回枚舉常量的序數(它在枚舉聲明中的位置,其中初始常量序數爲零)。 大多數程序員不會使用此方法。它被設計用於複雜的基於枚舉的數據結構,好比 EnumSet
和 EnumMap
。
4)String toString():返回枚舉常量的名稱,它包含在聲明中。能夠重寫此方法,雖然通常來講沒有必要。當存在更加「程序員友好的」字符串形式時,應該使用枚舉類型重寫此方法。
5)public static <T extends Enum<T>> T valueOf(Class<T> enumType,String name):返回帶指定名稱的指定枚舉類型的枚舉常量。名稱必須與在此類型中聲明枚舉常量所用的標識符徹底匹配。(不容許使用額外的空白字符。)
正如前面看到的,當程序使用System.out.println(s)語句來打印枚舉值時,實際上輸出的是該枚舉值得toString()方法,也就是輸出該枚舉值的名字。
歡迎關注微信公衆號【Java典籍】,收看更多Java技術乾貨!
▼微信掃一掃下圖↓↓↓二維碼關注