当我头一次看到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年的编辑。