引自《java编程思想》

枚举类型

Java 5 中添加了一个看似很小的特性 enum 关键字,它使得我们在需要群组并使用枚举类型集时,可以很方便地处理。以前,你需要创建一个整数常量集,但是这些值并不会将自身限制在这个常量集的范围内,因此使用它们更有风险,而且更难使用。枚举类型属于非常普遍的需求,C、C++ 和其他许多语言都已经拥有它了。在 Java 5 之前,Java 程序员必须了解许多细节并格外仔细地去达成 enum 的效果。现在 Java 也有了 enum,并且它的功能比 C/C++ 中的完备得多。下面是个简单的例子:

public enum Spiciness {
    NOT, MILD, MEDIUM, HOT, FLAMING
}

这里创建了一个名为 Spiciness 的枚举类型,它有5个值。由于枚举类型的实例是常量,因此按照命名惯例,它们都用大写字母表示(如果名称中含有多个单词,使用下划线分隔)。

要使用 enum,需要创建一个该类型的引用,然后将其赋值给某个实例:

public class SimpleEnumUse {
    public static void main(String[] args) {
        Spiciness howHot = Spiciness.MEDIUM;
        System.out.println(howHot);
    }
}

输出:

MEDIUM

在你创建 enum 时,编译器会自动添加一些有用的特性。例如,它会创建 toString() 方法,以便你方便地显示某个 enum 实例的名称,这从上面例子中的输出可以看出。编译器还会创建 ordinal() 方法表示某个特定 enum 常量的声明顺序,static values() 方法按照 enum 常量的声明顺序,生成这些常量值构成的数组:

public class EnumOrder {
    public static void main(String[] args) {
        for (Spiciness s: Spiciness.values()) {
            System.out.println(s + ", ordinal " + s.ordinal());
        }
    }
}

输出:

NOT, ordinal 0
MILD, ordinal 1
MEDIUM, ordinal 2
HOT, ordinal 3
FLAMING, ordinal 4

尽管 enum 看起来像是一种新的数据类型,但是这个关键字只是在生成 enum 的类时,产生了某些编译器行为,因此在很大程度上你可以将 enum 当作其他任何类。事实上,enum 确实是类,并且具有自己的方法。

enum 有一个很实用的特性,就是在 switch 语句中使用:

public class Burrito {
    Spiciness degree;
    
    public Burrito(Spiciness degree) {
        this.degree = degree;
    }
    
    public void describe() {
        System.out.print("This burrito is ");
        switch(degree) {
            case NOT:
                System.out.println("not spicy at all.");
                break;
            case MILD:
            case MEDIUM:
                System.out.println("a little hot.");
                break;
            case HOT:
            case FLAMING:
            default:
                System.out.println("maybe too hot");
        }
    }
    
    public static void main(String[] args) {
        Burrito plain = new Burrito(Spiciness.NOT),
        greenChile = new Burrito(Spiciness.MEDIUM),
        jalapeno = new Burrito(Spiciness.HOT);
        plain.describe();
        greenChile.describe();
        jalapeno.describe();
    }
}

输出:

This burrito is not spicy at all.
This burrito is a little hot.
This burrito is maybe too hot.

由于 switch 是在有限的可能值集合中选择,因此它与 enum 是绝佳的组合。注意,enum 的名称是如何能够倍加清楚地表明程序的目的的。