您的位置:首页 > 编程语言 > Java开发

Java枚举,酷!

2014-01-10 14:57 260 查看
当我头一次看到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年的编辑。

转自 :http://blog.csdn.net/rmartin/article/details/1046161
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: