在 J2SE 5.0 (Tiger) 中,透過新的 enum 關鍵字建立指定的物件集合,即可創建一個枚舉類型。每個指定的值可視為該類別的一個實例,這提供了指定整數集合無法比擬的編譯時期類型安全。下列範例展示了如何創建枚舉類型,並將類型安全的枚舉值作為輔助方法的參數。該枚舉類型的 values() 方法會返回該類型不同值的有序陣列。
public class Loop {
enum Size {
Small,
Medium,
Large
}
public static void main(String args[]) {
for (Size s : Size.values()) {
helper(s);
}
}
private static void helper(Size s) {
System.out.println("Size value: " + s);
}
}
使用 enum 關鍵字創建新的枚舉類型時,實際上是在創建 java.lang.Enum 類別的子類別,其中枚舉類型符合通用模式 Class Enum<E extends Enum<E>>,而 E 代表枚舉類型的名稱。枚舉類型的每一個值都會映射到 protected Enum(String name, int ordinal) 建構函數中,此處每個值的名稱被轉換為字串,序數代表宣告順序。換句話說,enum Size {Small, Medium, Large} 將對應到以下建構函數呼叫:
new Enum<Size>("Small", 0);
new Enum<Size>("Medium", 1);
new Enum<Size>("Large", 2);
不必將建構函數的使用限制為間接 Enum 建構函數呼叫。使用 enum 關鍵字時,將創建 Enum 的子類別。您可以使用參數為定義的每個名稱添加自訂的建構函數呼叫。名稱宣告可視為對建構函數的呼叫,無需添加 new 關鍵字。這種方式允許將資料作為參數值傳遞給建構函數呼叫,如範例 3 所示。該參數代表 Size 物件枚舉集合的定價因子。
public class Sample {
enum Size {
Small(0.8),
Medium(1.0),
Large(1.2);
double pricingFactor;
Size(double p) {
pricingFactor = p;
}
}
public static void main(String args[]) {
Size s = Size.Large;
double d = s.pricingFactor;
System.out.println(s + " Size has pricing factor of " + d);
}
}
執行該程式將返回給定 Size 的定價因子。您還可以定義類似 getPricingFactor() 的方法,並將 pricingFactor 欄位設為 private,以更符合 JavaBean 屬性的規範。範例 4 給前面的例子添加了一個方法:
public class Sample2 {
enum Size {
Small(0.8),
Medium(1.0),
Large(1.2);
private double pricingFactor;
Size(double p) {
pricingFactor = p;
}
public double getPricingFactor() {
return pricingFactor;
}
}
public static void main(String args[]) {
Size s = Size.Large;
double d = s.getPricingFactor();
System.out.println(s + " Size has pricing factor of " + d);
}
}
對於這兩種情況,輸出均為:
Large Size has pricing factor of 1.2
因為使用者定義的枚舉類型是 Enum 類型的子類別,所以您繼承了該類別的所有方法。下面列出了完整的方法集合(E 代表枚舉類型自身):
public int compareTo(E e)public boolean equals(Object o)public final Class<E> getDeclaringClass()public int hashCode()public String name()public int ordinal()public String toString()public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)有些方法看起來很熟悉,而其他一些方法則是 Enum 類別特有的。compareTo()、equals() 和 hashCode() 是典型的 Object 和 Comparable 方法,其中 compareTo() 報告宣告元素的順序。name() 和 ordinal() 方法返回建構函數參數,而 toString() 返回名稱。
getDeclaringClass() 和 valueOf() 方法需要稍多一些解釋。getDeclaringClass() 方法類似於 Object 的 getClass() 方法,但它不一定返回相同的類別。根據這個方法的 Javadoc 說明:
對於具有特定於常數的類別主體的 enum 常數,該方法返回的值可能不同於
Object.getClass()方法返回的值。
接下來,我將解釋特定於常數的類別主體。valueOf() 方法是靜態的,它允許您從類型的名稱中創建枚舉的值。
特定於常數的類別主體是 enum 關鍵字的一個受支援特性;不過,它們的使用應該受到嚴格限制。這個概念深入到將枚舉類型的每個元素視為一個子類別的領域。例如,在前面的例子中,Size 枚舉類型有一個定價因子參數和 getPricingFactor() 方法。但沒有建構函數參數,範例 5 展示了如何利用特定於常數的主體來做同樣的事。我們添加了一些額外的大小來讓這個例子更有趣。在這裡,Small 的定價因子是 0.8,而 ExtraLarge 和 ExtraExtraLarge 的定價因子是 1.2。其餘的大小則採用預設值 1.0。
public class Sample3 {
enum Size {
Small(0.8),
Medium(1.0),
Large(1.0),
ExtraLarge(1.2),
ExtraExtraLarge(1.2);
private double pricingFactor = 1.0;
Size(double p) {
pricingFactor = p;
}
public double getPricingFactor() {
return pricingFactor;
}
}
// ... 使用方式同上
}