枚舉類型是指由一組固定的常量組成合法值的類型。例如一年中的季節,太陽系中的行星或者一副牌中的花色。在編程語言中還沒有引入枚舉類型之前,表示枚舉類型的常用模式是聲明一組具名的int常量,每個類型成員一個常量:
public static final int APPLE_FUJI = 0;
public static final int APPLE_PIPPIN = 1;
public static final int APPLE_GRANNY_SMITH = 2;
public static final int ORANGE_NAVEL = 0;
public static final int ORANGE_TEMPLE = 1;
public static final int ORANGE_BLOD = 2;
這種方法稱作int 枚舉模式,存在着諸多不足。它在類型安全性和使用方便性方面沒有任何幫助。如果你將apple傳到想要orange的方法中,編譯器也不會出現警告,還會用==操作符將apple與orange進行對比,甚至更糟糕。
JAVA枚舉背後的基本想法非常簡單:它們是通過公有的靜態final域爲枚舉常量導出實例的類。因爲沒有可以訪問的構造器,枚舉類型是真正的final。因爲客戶端既不能創建枚舉常量導出的類。因爲沒有可以訪問的構造器,枚舉類型是真正的final 。因爲客戶端既不能創建枚舉類型的實例,也不能對它進行擴展,因此很可能 沒有實例,而只有聲明過的枚舉常量。換句話說,枚舉類型是實例受控的。它們是單例的泛型化,本質上是單元素的枚舉。
public enum PayrollDay {
MONDAY(PayType.WEEKDAY), TUESDAY(PayType.WEEKDAY), WEDNESDAY(
PayType.WEEKDAY), THURSDAY(PayType.WEEKDAY), FRIDAY(PayType.WEEKDAY), SATURDAY(
PayType.WEEKEND), SUNDAY(PayType.WEEKEND);
private final PayType payType;
PayrollDay(PayType payType) {
this.payType = payType;
}
double pay(double hoursWorked, double payRate) {
return payType.pay(hoursWorked, payRate);
}
private enum PayType {
WEEKDAY {
double overtimePay(double hours, double payRate) {
return hours <= HOURS_PER_SHIFT ? 0 : (hours - HOURS_PER_SHIFT)
* payRate / 2;
}
},
WEEKEND {
double overtimePay(double hours, double payRate) {
return hours * payRate / 2;
}
};
private static final int HOURS_PER_SHIFT = 8;
abstract double overtimePay(double hours, double payRate);
double pay(double hoursWorked, double payRate) {
double basePay = hoursWorked * payRate;
return basePay + overtimePay(hoursWorked, payRate);
}
}
}
總之:與int常量相比,枚舉的類型優勢是不言而喻的。枚舉要易讀得多,也更加安全,功能更加強大。許多枚舉都不需要顯式的構造器或者成員,但許多其它枚舉則受益於“每個常量與屬性的關聯”以及“提供行爲受這個屬性影響的方法”。只有極少數的枚舉受益於將多種行爲與單個方法關聯。在這種相對少見的情況下,特定於常量的方法要優先於啓用自有值的枚舉。如果多個枚舉常量同時享有相同的行爲,則考慮策略枚舉。
摘自:effective java