enum关键字用于创建一个新类型,其中包含一组数量有限的命名变量,并视这些变量为常规程序组件。实践表明这是一种非常有用的类型
你可以调用枚举类型中的 values() 方法来遍历枚举常量列表。values() 方法生成一个由枚举常量组成的数组,其中常量的顺序和常量声明的顺序保持一致,这样你就可以方便地(比如通过for-in循环)使用结果数组了。
当创建枚举类型时,编译器会为你生成一个辅助类,这个类自动继承自java.lang.Enum。java.lang.Enum提供了下例所示的一些功能:
EnumClass.java
enum Shrubbery {GROUND, CRAWLING, HANGING}
public class EnumClass {
public static void main(String[] args) {
for (Shrubbery s : Shrubbery.values()) {
System.out.println(s + " ordinal: " + s.ordinal());
System.out.print(s.compareTo(Shrubbery.CRAWLING) + " ");
System.out.print(s.equals(Shrubbery.CRAWLING) + " ");
System.out.println(s == Shrubbery.CRAWLING);
System.out.println(s.getDeclaringClass());
System.out.println(s.name());
System.out.println("********************");
}
// Produce an enum value from a String name:
for (String s : "HANGING CRAWLING GROUND".split(" ")) {
Shrubbery shrub = Enum.valueOf(Shrubbery.class, s);
System.out.println(shrub);
}
}
}
运行结果:
ordinal() 方法返回一个从0开始的int值,代表每个枚举实例的声明顺序。你可以放心地使用 == 来比较枚举实例( equals() 和 hashCode() 方法会由编译器自动为你生成)。Enum 类实现了 Comparable 接口(因此可比较), 所以自动包含了 compareTo() 方法,另外它还实现了 Serializable 接口(因此可序列化)。
如果调用枚举实例的 getDeclaringClass()方法,则会得到该枚举实例所属的外部包装类。
name() 方法返回枚举实例被声明的名称,使用 toString() 同样也可以返回该名称。
value0f() 方法是 Enum 类中的静态方法,它根据传入的 String, 返回名称与该 String 匹配的枚举实例。如果匹配的实例不存在,则抛出异常。
静态导入枚举类型
下面是基础卷第 6 章中 Burrito.java 类的一个变体:
SpicinessEnum.java
public enum SpicinessEnum {
NOT, MILD, MEDIUM, HOT, FLAMING
}
Burrito2.java
public class Burrito2 {
SpicinessEnum degree;
public Burrito2(SpicinessEnum degree) {
this.degree = degree;
}
@Override
public String toString() {
return "Burrito is " + degree;
}
public static void main(String[] args) {
System.out.println(new Burrito2(NOT));
System.out.println(new Burrito2(MEDIUM));
System.out.println(new Burrito2(HOT));
}
}
运行结果:
Burrito is NOT
Burrito is MEDIUM
Burrito is HOT
static import 将所有的枚举实例标识符都引入了本地命名空间,因此它们不需要显式地使用枚举类型来限定。相较于显式地用枚举类型来限定枚举实例,哪种方式更好呢?这很大程度上要视代码的复杂程度而定。编译器肯定会保障类型的正确性,所以你唯一要关心的就是代码的可读性如何。一般来说不会有大问题,但还是要根据具体情况评估。
注意,如果枚举定义在同一个文件中,或者定义在默认包中,则无法使用该方式(显然在Sun公司的内部,对于是否允许这种情况有过一些争论)。