它提供了编译期类型安全,而整数枚举根本没有提供任何类型安全。
它们对被枚举的类型提供了一个适当的命名空间――在整数枚举中你必须前置一个常数来得到命名空间。
它更强大――整数枚举被编译进了程序,如果你增加、删除或者重置了常数的顺序你必须重新编译你的程序。
输出的值是包含各种信息的――如果你打印一个整数枚举,你只会得到一个数字。
它们是对象,你可以把他们放入集合中。
它们本质上是类,所以你能增加任意的属性和方法。
哇,这么厉害!那么新的类型安全的枚举语言特性和你书中类型安全的模式有什么关系?这个特性是对类型安全模式的首次语言上的简单支持。那些有差不多半页、冗长的、易错的支持模式的代码现在看起来很像C/C++中枚举的声明:enum Season { winter, spring, summer, fall }
不过它用起来却跟C/C++中的枚举大相径庭,你可以使用我们刚才讨论的所有的强大的功能。它甚至修正了类型安全模式的主要的缺点:你可以把这个新的语言特性和Switch语句用在一起。
你能给我们举例说明一下类型安全的枚举的强大功能吗? 当然可以。下面的这个枚举代表了一个美国硬币:public enum Coin {
penny(1), nickel(5), dime(10), quarter(25);
Coin(int value) { this.value = value; }
private final int value;
public int value() { return value; }
}
看看,这个常数声明怎样调用了一个构造函数,输入一个整数代表分?还有,这个值怎样存放在一个带有公共访问方法的私有变量里面?这个就可以勾画出你能做的事情的轮廓。
您能给我一个类使用您上面定义的enum吗? 我正准备要说到这个。下面是一个小的例子,它用来输出分币表中各个分币的值和颜色。public class CoinTest {
public static void main(String[] args) {
for (Coin c : Coin.VALUES)
System.out.println(c + ": \t"
+ c.value() +"¢ \t" + color(c));
}
private enum CoinColor { copper, nickel, silver }
private static CoinColor color(Coin c) {
switch(c) {
case Coin.penny: return CoinColor.copper;
case Coin.nickel: return CoinColor.nickel;
case Coin.dime:
case Coin.quarter: return CoinColor.silver;
default: throw new AssertionError("Unknown coin: " + c);
}
}
}
看看我们如何声明另外一个关于颜色的枚举?一个叫做nickeld的硬币和一个叫做nickel的颜色根本不会引起什么冲突,因为硬币和颜色都有它们自己的命名空间。同时你可以看到我们可以把枚举常数和Switch语句用在一起。当你希望给一个枚举类增加一个方法而不想修改你的应用程序的时候,这个性质非常有用。