在Java中的枚举。

Enum in Java. Advantages?

在类似于类的Java中枚举EnUM有哪些优点,而不仅仅是C/C++中的常量集合?


您可以获得有效值的自由编译时检查。使用

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

不保证

1
2
3
void selectOption(int option) {
...
}

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


类型安全是一个原因。

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

1
AddItem(HttpMethod.POST, ProductEntry.class),


Java 5枚举源于Joshua Bloch的有效Java(第一版)中的类型化枚举模式,以避免C/C++ +C/x中的枚举陷阱(这是简单地隐藏的int常量)和Java中的最终静态int常量。

主要是int常量和int枚举不是类型安全的。您可以传递任何int值。在C/C++中你可以做到这一点:

1
2
3
4
5
enum A { one, two, three };
enum B { beef, chicken, pork } b = beef;

void func(A a) { ... }
func((A)b);

不幸的是,来自高效Java的类型安全枚举模式有很多样板,并非所有都是显而易见的。最值得注意的是,您必须重写私有方法EDCOX1(5),以阻止Java在反序列化过程中创建新实例,这将破坏简单的引用检查(即使用EDCOX1×6的操作符而不是EDCOX1(7))。

因此Java 5枚举提供了优于int的优势:

  • 类型安全;
  • Java 5枚举可以具有行为和实现接口;
  • Java 5枚举具有一些非常轻量级的数据结构,如EDCOX1、8和EDCX1 9。

Java 5枚举胜过使用类:

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


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

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


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


您可以使用枚举有效地实现单例^ ^:

1
2
3
public enum Elvis {
    INSTANCE
}


使枚举成为可以包含固定常量集的引用类型已导致高效的映射实现(如Enummap)和设置实现(如Enumset(JDK类))。

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

枚举将地图的丰富性和类型安全性与数组的速度(有效Java)相结合。


使用枚举的好处:可以创建一个对象以与枚举相同的方式工作。事实上,在版本5之前,枚举甚至不包含在Java语言中。然而,枚举使代码更具可读性,并为程序员错误提供更少的空间。

OCA Java SE 7 Programmer I Study Guide


唯一的真正优势是它可以在switch语句中使用。枚举所能做的所有其他事情都可以用普通的普通类和一个private构造函数来完成,后者的实例依次声明为相关类的public static final字段(typesafe模式)。枚举的另一个优点是它明显地使代码没有普通类那样冗长。

但是如果我没有错,在C++中(或者是C?)您可以在switch语句中使用String。因此,与C++相比,枚举在Java中的优势是微不足道的。然而,对于Java 7提出了同样的事情,不确定它是否能实现。


枚举本身就是一个类型-不能使用不存在的枚举,也不能放入其他类似的常量。而且,您还可以枚举它们,这样代码就可以更简洁。

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