當我頭一次看到Java 5中的新登場的枚舉類型(譯註:enum)時,我還是持懷疑態度的。這些枚舉類型允許你定義成員和方法(譯註:variables and methods),甚至是抽象方法!你能用它來做什麼呢?嗯,我現在已經找到了這個問題的答案。(至少是部分的)
在評閱和改進外面的一些源碼的過程中,我有機會找到了一組用來代表月份的私有靜態常量(譯註:static final constants),並把他們轉換成了Month枚舉。起初,這個Month枚舉僅僅是個簡單的枚舉,但隨着我進一步改進這些源碼時,我發現了越來越多的操作月份常量的方法,或者說,是一些與月份常量緊密關聯的方法。每次我發現一個就把它放到Month枚舉之中。結果如下:
import java.text.DateFormatSymbols;
public enum Month {
JANUARY(1), FEBRUARY(2), MARCH(3),
APRIL(4), MAY(5), JUNE(6),
JULY(7), AUGUST(8), SEPTEMBER(9),
OCTOBER(10),NOVEMBER(11),DECEMBER(12);
private static DateFormatSymbols dateFormatSymbols = new DateFormatSymbols();
private static final int[] LAST_DAY_OF_MONTH =
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
public int index;
Month(int index) {
this.index = index;
}
public static Month make(int monthIndex) {
for (Month m : Month.values()) {
if (m.index == monthIndex)
return m;
}
throw new IllegalArgumentException("Invalid month index " + monthIndex);
}
public int lastDay() {
return LAST_DAY_OF_MONTH[index];
}
public int quarter() {
return 1 + (index - 1) / 3;
}
public String toString() {
return dateFormatSymbols.getMonths()[index - 1];
}
public String toShortString() {
return dateFormatSymbols.getShortMonths()[index - 1];
}
public static Month parse(String s) {
s = s.trim();
for (Month m : Month.values())
if (m.matches(s))
return m;
try {
return make(Integer.parseInt(s));
}
catch (NumberFormatException e) {}
throw new IllegalArgumentException("Invalid month " + s);
}
private boolean matches(String s) {
return s.equalsIgnoreCase(toString()) ||
s.equalsIgnoreCase(toShortString());
}
}
我發現這很值得注意,也很有用。現在我就可像這樣來描述事情:
Month m = Month.parse(inputString);
或是
Month m...;
int lastDay = m.lastDay();
Java 5的枚舉並不定義常量,它們在一個類之中定義了單例(譯註1)對象。有一個類叫Month,還有另外一個代表JANUARY的類從Month派生。這個JANUARY類有唯一的一個單例叫JANUARY。這個JANUARY類的單例就是JANUARY的枚舉對象。
事實上,枚舉是一種創建單例類的方法。每個枚舉對象決不會擁有超過一個的實例,而且這個實例在枚舉被使用之前(可能在加載過程中)就被構建了。而現在枚舉對象就是一些類,它們充滿着類天生的各種技能。下次你再想要單例的時候考慮一下這個:
enum Database {
INSTANCE;
public void open() {...}
...
}
你可以像這樣來使用它:
Database.INSTANCE.open(...);
譯註:
1,單例,原文singleton,一種常用的設計模式,詳細介紹可參見uncle bob的著作《敏捷軟件開發:原則、模式與實踐》一書。
(原文鏈接網址:http://www.butunclebob.com/ArticleS.UncleBob.JavaEnums; Robert C. Martin的英文blog網址: http://www.butunclebob.com/ArticleS.UncleBob)
作者簡介:Robert C. Martin是Object Mentor公司總裁,面向對象設計、模式、UML、敏捷方法學和極限編程領域內的資深顧問。他不僅是Jolt獲獎圖書《敏捷軟件開發:原則、模式與實踐》(中文版)(《敏捷軟件開發》(英文影印版))的作者,還是暢銷書Designing Object-Oriented C++ Applications Using the Booch Method的作者。Martin是Pattern Languages of Program Design 3和More C++ Gems的主編,並與James Newkirk合著了XP in Practice。他是國際程序員大會上著名的發言人,並在C++ Report雜誌擔任過4年的編輯。