Java在JDK 5版本中从语言级别上引入了枚举支持。枚举是指一个经过排序的、被打包成一个单一实体的项列表。一个枚举的实例可以使用枚举项列表中任意单一项的值。可能的最简单的枚举是下面所显示的Colors枚举:
public enum Colors { red, green, blue }
它们给出了将一个任意项同另一个项相比较的能力,并且可以在一个已定义项列表中进行迭代。枚举(在Jave中简称为enum)是一个特定类型的类。所有枚举都是Java中的新类java.lang.Enum的隐式子类。此类不能手工进行子类定义。
在Java中内置枚举支持有许多好处。枚举是类型安全的,性能可与使用常量相媲美。枚举中的常量名称无需用枚举名称进行限定。客户端不需要建立对枚举中常量的了解,因此可以容易地对枚举进行修改,而无需修改客户端。如果常量从枚举中被删除了,那么客户端将会失败并且将会收到一个错误消息。枚举中的常量名称可以被打印,因此除了仅仅得到列表中项的序号外还可以获取更多信息。这也意味着常量可用作集合的名称,例如HashMap。
因为在Java中一个枚举就是一个类,它也可以有域和方法,并且实现接口。枚举在switch语句中可以一种直接的方式被使用,并且可以便于程序员相对简单地去理解和使用。
下面是一个基本的枚举声明,以及它在switch语句中的使用。如果希望追踪某个用户正在使用什么操作系统,就可以使用一个操作系统的枚举,即OperatingSystems enum。注意,因为一个枚举实际上是一个类,那么如果在同一个文件中的其他类是公用的,则枚举就不能是公用的了。同时也要注意,在switch语句中,常量名称不能用常量所在枚举的名称限制。这些细节将由编译器基于switch子句中使用的enum类型来自动处理:
import java.util.*;
enum OperatingSystems {
windows, unix, linux, macintosh
}
public class EnumExample1 {
public static void main(String args[])
{
OperatingSystems os;
os = OperatingSystems.windows;
switch(os) {
case windows:
System.out.println("You chose Windows!");
break;
case unix:
System.out.println("You chose Unix!");
break;
case linux:
System.out.println("You chose Linux!"};
break;
case macintosh:
System.out.println{"You chose Macintosh!");
break;
default:
System.out.println{"I don't know your OS."};
break;
}
}
}
Java.lang.Enum类实现了Comparable和Serializable接口。在该类中已提供了比较枚举以及将它们序列化成为一个数据源的细节。不能将一个enum标记为abstract,除非每一个常量都有一个类主体,并且这些类主体覆盖了enum中的抽象方法。同时也要注意,枚举不能使用new进行实例化。编译器将会告知“enum types may not be instantiated.”(枚举类型不可以被实例化)。
Java引入了两个新集合:EnumSet和EnumMap,它们只是想在使用enum时优化集和映射的性能。枚举可以与当前已存在的集合类一起使用,或者在需要剪裁成枚举的优化活动时与新集合一起使用。
方法可声明在一个enum中。但是,对一个正在定义的构造方法来说会有所限制。构造函数不能链接超类构造方法,除非超类是另一个enum。enum中的每个常量都可以有一个类主体,但是因为这实际上是一个匿名类,因此不能定义一个构造函数。
也可以向枚举和单个enum常量添加属性。enum常量后面也可以跟有参数,这些参数被传递给在enum中定义的构造函数。
以下是一个具有域和方法的枚举例子:
enum ProgramFlags {
showErrors(0x01),
includeFileOutput(0x02),
useAlternateProcessor{0x04};
private int bit;
ProgramFlags(int bitNumber)
{
bit = bitNumber;
}
public int getBitNumber()
{
return(bit);
}
}
public class EnumBitmapExample {
public static void main(String args[])
{
ProgramFlags flag = ProgramFlags.showErrors;
System.out.println("Flag selected is: "+
flag.ordinal() +
"which is" +
flag.name());
}
}