【发布时间】:2010-01-16 14:36:33
【问题描述】:
在 Java 中使枚举类似于类,而不是像 C/C++ 中的常量集合,有哪些优点?
【问题讨论】:
在 Java 中使枚举类似于类,而不是像 C/C++ 中的常量集合,有哪些优点?
【问题讨论】:
您可以免费在编译时检查有效值。使用
public static int OPTION_ONE = 0;
public static int OPTION_TWO = 1;
不保证
void selectOption(int option) {
...
}
只接受 0 或 1 作为参数值。使用枚举,这是有保证的。此外,这会导致更多的自我记录代码,因为您可以使用代码完成来查看所有枚举值。
【讨论】:
类型安全是原因之一。
另一个 that I find more important 是您可以将元数据附加到 Java 中的枚举值。例如,您可以使用枚举来定义 Web 服务的合法操作集,然后为请求类型和数据类附加元数据:
AddItem(HttpMethod.POST, ProductEntry.class),
【讨论】:
Java 5 枚举源自Joshua Bloch 的Effective Java(第一版)中的类型安全枚举模式,以避免 C/C++/C# 中枚举的缺陷(它们只是隐蔽的 int 常量)和在 Java 中使用 final 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 中的类型安全枚举模式有很多样板,并不是所有的都很明显。最值得注意的是您必须重写 private 方法 readResolve 以阻止 Java 在反序列化时创建新实例,这会破坏简单的引用检查(即使用 == 运算符而不是 equals()) .
因此,Java 5 枚举比 int 具有以下优势:
EnumSet 和 EnumMap。Java 5 枚举了这些优于仅使用类的优势:
readResolve() 等);【讨论】:
readResolve() 没什么大不了的。我经常为实例数量有限的类执行此操作。有时enum 简化了这些类的定义,有时则不然。为工作使用正确的工具。
枚举已经是class in Java。
如果您要问为什么这样做更好,我会说更好的类型安全性和添加除序数值之外的其他属性的能力会浮现在脑海中。
【讨论】:
除了更好的类型安全性之外,您还可以在枚举中定义自定义行为(请参阅 Effective Java 以获得一些很好的示例)。
【讨论】:
你可以使用枚举来有效地实现单例^^:
public enum Elvis {
INSTANCE
}
【讨论】:
使 enum 成为可以包含一组固定常量的引用类型导致了高效的 Map 实现,如 EnumMap 和 Set 实现,如 EnumSet(JDK 类)。
来自 EnumMap 的 javadoc:
用于枚举类型键的专用 Map 实现。枚举映射中的所有键都必须来自创建映射时显式或隐式指定的单个枚举类型。枚举映射在内部表示为数组。这种表示非常紧凑和高效。
EnumMap 结合了 Map 的丰富性和类型安全性以及数组的速度 (Effective Java)。
【讨论】:
枚举本身就是一种类型——你不能使用一个不存在的枚举,或者放入一些其他类似的常量。而且,你可以枚举它们,让代码更简洁。
使用静态常量可能会导致维护噩梦 - 尤其是当它们区域分散时。
【讨论】:
唯一的真正优点是它可以在switch 语句中使用。枚举能够做的所有其他事情都可以使用带有private 构造函数的普通类来完成,其实例又被声明为相关类的public static final 字段(类型安全模式)。 enum 的另一个优点显然是它使代码不像普通的普通类那样冗长。
但如果我没记错的话,在 C++(或者是 C#?)中,您可以在 switch 语句中使用 String。因此,与 C++ 相比,Java 中枚举的优势可以忽略不计。但是,Java 7 也提出了同样的建议,不确定是否会成功。
【讨论】:
使用枚举的好处: 可以创建对象以与枚举相同的方式工作。实际上, 直到 5.0 版,枚举才包含在 Java 语言中。然而, 枚举使代码更具可读性,并为程序员提供更少的错误空间。
OCA Java SE 7 程序员 I 学习指南
【讨论】: