枚舉
從 JDK 5 開(kāi)始, 枚舉被添加到了 Java 語(yǔ)言中, 和其它語(yǔ)言中的描述相似, 但是這種相似只是表面上的.
枚舉的基礎(chǔ)知識(shí)
創(chuàng)建枚舉需要使用 enum
關(guān)鍵字, 例如:
enum Apple {
Jonathan, GoldenDel, RedDel, Winesap, Cortland
}
標(biāo)識(shí)符 Jonathan
, GoldenDel
等被稱為枚舉常量. 每個(gè)枚舉常量被隱式聲明為 Apple 的公有,靜態(tài) final 成員.
此外, 枚舉常量的類型是聲明它們的枚舉類型, 對(duì)于這個(gè)例子為 Apple.
定義了枚舉之后, 可以創(chuàng)建枚舉類型的變量. 但是, 盡管枚舉定義了類類型, 卻不能使用 new
實(shí)例化枚舉. 反而, 枚舉變量的聲明和使用方式在許多方面與基本類型相同.
下面這行代碼將 ap 聲明為 Apple 枚舉類型的變量:
Apple ap;
因?yàn)?ap
是 Apple 類型, 所以只能被賦值為(或包含)在 Apple 枚舉中定義的那些值.
例如, 下面這行代碼將 ap
賦值為 RedDel;
ap = Apple.RedDel;
可以使用關(guān)系運(yùn)算符 ==
比較兩個(gè)枚舉常量的相等性. 例如, 下面這條語(yǔ)句比較 ap
的值和 GoldenDel
常量:
if (ap == Apple. GoldenDel) // ...
枚舉值也可以用于控制 switch
語(yǔ)句. 當(dāng)然, 所有的 case
語(yǔ)句使用的常量的枚舉類型, 都必須與 switch
表達(dá)式使用的枚舉類型相同.
switch (ap) {
case Jonathan:
// ...
case Winesap:
// ...
注意在
case
語(yǔ)句中, 枚舉常量的名稱沒(méi)有使用枚舉類型的名稱進(jìn)行限定. 也就是說(shuō), 使用的是Winesap
而不是Apple.Winesap
.
這是因?yàn)?switch 表達(dá)式中的枚舉類型已經(jīng)隱式指定了 case 常量的枚舉類型, 所以在 case 語(yǔ)句中不需要使用枚舉類型的名稱對(duì)常量進(jìn)行限定. 實(shí)際上, 如果試圖這么做的話, 會(huì)造成編譯時(shí)錯(cuò)誤.
values() 和 valuesOf() 方法
所有枚舉都自動(dòng)包含兩個(gè)預(yù)定義方法: values() 和 valuesOf() 方法. 它們的一般形式如下所示:
public static enum-type [ ] values()
public static enum-type valueOf(String str)
values() 方法返回一個(gè)包含枚舉常量列表的數(shù)據(jù), valueOf()方法返回與傳遞到參數(shù) str 的字符串相對(duì)應(yīng)的常量.
Java 枚舉是類類型
Java 枚舉是類類型. 雖然不能使用 new
實(shí)例化枚舉, 但是枚舉卻又許多和類相同的功能.
枚舉定義了類, 這為 Java 枚舉提供了超乎尋常的功能. 例如, 可以為枚舉提供構(gòu)造函數(shù), 添加實(shí)例變量和方法, 甚至可以實(shí)現(xiàn)接口.
需要理解的重要一點(diǎn)是: 每個(gè)枚舉常量都是枚舉類型的對(duì)象. 因此, 如果為枚舉定義了構(gòu)造函數(shù), 那么當(dāng)創(chuàng)建每個(gè)枚舉常量時(shí)都會(huì)調(diào)用該構(gòu)造函數(shù).
分析下面 Apple 枚舉:
enum Apple{
Jonathan(10), GoldenDel(9), RedDel(20), Winesap(15), Cortland(8);
private int price;
Apple(int p) { price = p;}
int getPrice() { return price; }
}
這個(gè)版本的 Apple 枚舉添加了三個(gè)內(nèi)容: 第一個(gè)內(nèi)容是實(shí)例變量 price, 用于保存每種蘋(píng)果的價(jià)格; 第二個(gè)內(nèi)容是 Apple 構(gòu)造函數(shù), 它以蘋(píng)果的價(jià)格作為參數(shù); 第三個(gè)內(nèi)容是 getPrice() 方法, 用于返回 Price 變量的值.
當(dāng)在 main()
方法中聲明變量 ap 時(shí), 對(duì)于每個(gè)特定的常量調(diào)用 Apple 構(gòu)造函數(shù)一次.
注意指定構(gòu)造函數(shù)參數(shù)的方式, 通過(guò)將它們放置到每個(gè)常量后面的圓括號(hào)中來(lái)加以指定, 如下所示:
Jonathan(10), GoldenDel(9), RedDel(20), Winesap(15), Cortland(8);
這些數(shù)值被傳遞給 Apple()
的參數(shù) p, 然后將這些值賦值給 price
變量. 再?gòu)?qiáng)調(diào)一次, 為每個(gè)常量調(diào)用構(gòu)造函數(shù)一次.
因?yàn)槊總€(gè)枚舉常量都有自己的 price
變量副本, 所以可以調(diào)用 getPrice()
方法來(lái)獲取指定類型蘋(píng)果的價(jià)格.
Apple.Winesap.getPrice();
枚舉繼承自 Enum 類
盡管聲明枚舉時(shí)不能繼承超類, 但是所有枚舉都自動(dòng)繼承超類 java.lang.Enum
, 這個(gè)類定義了所有枚舉都可以使用的一些方法.
可以獲取用于指示枚舉常量在常量列表中位置的值, 這種稱為枚舉常量的序數(shù)值. 通過(guò) ordinal() 方法可以檢索序數(shù)值, 該方法的聲明如下所示:
final int ordinal();
該方法返回調(diào)用常量的序數(shù)值, 序數(shù)值從0開(kāi)始. 因此 Apple 枚舉中, Jonathan 的序數(shù)值為 0, GoldenDel 的序數(shù)值為 1.
可以使用 compareTo()
方法比較相同類型的兩個(gè)枚舉常量的序數(shù)值, 該方法的一半形式如下:
final int compareTo( enum-type e );
其中, enum-tpye 是枚舉的類型, e 是和調(diào)用常量進(jìn)行比較的常量. 請(qǐng)記住, 調(diào)用常量和 e 必須是相同的枚舉.
如果調(diào)用常量的序數(shù)值小于 e 的序數(shù)值, 那么 compareTo()
方法返回負(fù)值; 如果兩個(gè)序數(shù)值相同, 返回0; 如果調(diào)用常量的序數(shù)值大于 e 序數(shù)值, 就返回正值.