在Java中的枚举。 优点?

将Java中的枚举类似于类,而不仅仅是C / C ++中的常量集合有什么好处?

您可以免费编译有效值的编译时间。 运用

public static int OPTION_ONE = 0; public static int OPTION_TWO = 1; 

不保证

 void selectOption(int option) { ... } 

只接受0或1作为参数值。 使用枚举,这是有保证的。 此外,这会导致更多自我记录代码,因为您可以使用代码完成来查看所有枚举值。

类型安全是一个原因。

另一个我发现更重要的是,您可以将元数据附加到Java中的枚举值。 例如,您可以使用枚举来定义Web服务的合法操作集,然后附加请求类型和数据类的元数据:

 AddItem(HttpMethod.POST, ProductEntry.class), 

Java 5枚举源自Joshua Bloch的Effective Java (第一版)中的类型安全枚举模式,以避免C / C ++ / C#中的枚举陷阱(这些只是简洁的int常量)以及Java中的最终使用static int常量。

主要的int常量和int枚举不是类型安全的。 您可以传入任何int值。 在C / C ++中,您可以这样做:

 enum A { one, two, three }; enum B { beef, chicken, pork } b = beef; void func(A a) { ... } func((A)b); 

不幸的是,Effective Java的类型安全枚举模式有很多样板,并不是很明显。 最值得注意的是你必须覆盖私有方法readResolve来阻止Java在反序列化时创建新实例,这会破坏简单的引用检查(即使用==运算符而不是equals() )。

所以Java 5枚举提供了超过整数的这些优势:

  • 型号安全;
  • Java 5枚举可以具有行为和实现接口;
  • Java 5枚举有一些非常轻量级的数据结构,如EnumSetEnumMap

Java 5比使用类更能体现这些优势:

  • 不易出错的样板(私有构造函数, readResolve()等);
  • 语义正确。 你看到一些东西是一个枚举,你知道它只是代表一个价值。 你看到一堂课,你不确定。 也许在某处有一个静态的工厂方法等.Java 5枚举更清楚地表明了意图。

枚举已经是Java中的一个类 。

如果你问为什么这更好,我会说更好的类型安全性和除了单纯的序数值之外添加其他属性的能力会浮现在脑海中。

除了更好的类型安全性之外,您还可以在枚举中定义自定义行为(有关一些好例子,请参阅Effective Java )。

您可以使用枚举来有效地实现单身人士^^:

 public enum Elvis { INSTANCE } 

使枚举成为可以包含固定常量集的引用类型,可以实现像EnumMap这样的高效Map实现和EnumSet (JDK类)之类的Set实现。

来自EnumMap的javadoc:
用于枚举类型键的专用Map实现。 枚举映射中的所有键必须来自创建映射时显式或隐式指定的单个枚举类型。 枚举映射在内部表示为数组。 这种表现非常紧凑和高效。

EnumMap将Map的丰富性和类型安全性与数组的速度( Effective Java )相结合。

枚举本身就是一种类型 – 你不能使用不存在的枚举,或者放入其他类似的外观常量。 而且,您可以枚举它们,以便代码可以更简洁。

使用静态常量可能会导致维护噩梦 – 尤其是当它们的区域扩散时。

唯一真正的优点是它可以在switch语句中使用。 枚举能够实现的所有其他东西都可以通过普通的vanilla类来完成,其中private构造函数的实例又被声明为相关类的public static final字段(类型安全模式)。 enum的另一个优点显然是它使得代码比使用普通的vanilla类更简洁。

但是如果我没弄错,在C ++中(或者它是C#?)你可以在switch语句中使用String 。 因此,与C ++相比,Java中枚举的优势可以忽略不计。 但是,同样的事情被提议用于Java 7,不确定它是否会成功。

使用枚举的好处:可以创建对象以与枚举相同的方式工作。 实际上,在5.0版之前,枚举甚至没有包含在Java语言中。 但是,枚举使代码更具可读性,并为程序员错误提供更少的空间。

OCA Java SE 7程序员I学习指南