【问题标题】:Enum in Java. Advantages?Java中的枚举。优点?
【发布时间】:2010-01-16 14:36:33
【问题描述】:

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

【问题讨论】:

标签: java enums


【解决方案1】:

您可以免费在编译时检查有效值。使用

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

不保证

void selectOption(int option) {
...
}

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

【讨论】:

    【解决方案2】:

    类型安全是原因之一。

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

    AddItem(HttpMethod.POST, ProductEntry.class),
    

    【讨论】:

    • 小心这个。我经常看到人们使用带有属性而不是类的枚举。这可能导致使用枚举的周围代码在本质上非常奇怪和静态(有效地尝试将对象注入枚举),因为它们非常热衷于保留枚举而不是将所述枚举转换为适当的类并接受重构命中。
    • 这看起来很病态;想看一个例子。所以也许有些规则是有序的:没有可变状态,也没有行为。
    【解决方案3】:

    Java 5 枚举源自Joshua BlochEffective 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 具有以下优势:

    • 类型安全;
    • Java 5 枚举可以有行为并实现接口;
    • Java 5 枚举具有一些极其轻量级的数据结构,例如 EnumSetEnumMap

    Java 5 枚举了这些优于仅使用类的优势:

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

    【讨论】:

    • 覆盖readResolve() 没什么大不了的。我经常为实例数量有限的类执行此操作。有时enum 简化了这些类的定义,有时则不然。为工作使用正确的工具。
    【解决方案4】:

    枚举已经是class in Java

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

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

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

        public enum Elvis {
            INSTANCE
        }
        

        【讨论】:

        • -1 - 你应该避免单例,而不是找到“有效实现”它们的方法(顺便说一下,这种方法会进行加载时初始化,调试起来非常痛苦)
        • 我只是想指出,如果你需要/想要使用单例,这是 Java 中最好的方法
        • 顺便说一句,单身人士确实有其用途
        • +1 表示与问题相关的答案,即使它指向边缘情况。在我看来,因为答案反对某人的个人意识形态而投反对票是蹩脚的。
        【解决方案7】:

        使 enum 成为可以包含一组固定常量的引用类型导致了高效的 Map 实现,如 EnumMapSet 实现,如 EnumSet(JDK 类)。

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

        EnumMap 结合了 Map 的丰富性和类型安全性以及数组的速度 (Effective Java)。

        【讨论】:

          【解决方案8】:

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

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

          【讨论】:

            【解决方案9】:

            唯一的真正优点是它可以在switch 语句中使用。枚举能够做的所有其他事情都可以使用带有private 构造函数的普通类来完成,其实例又被声明为相关类的public static final 字段(类型安全模式)。 enum 的另一个优点显然是它使代码不像普通的普通类那样冗长。

            但如果我没记错的话,在 C++(或者是 C#?)中,您可以在 switch 语句中使用 String。因此,与 C++ 相比,Java 中枚举的优势可以忽略不计。但是,Java 7 也提出了同样的建议,不确定是否会成功。

            【讨论】:

              【解决方案10】:

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

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2011-01-20
                • 1970-01-01
                • 2010-12-10
                • 1970-01-01
                • 2011-07-09
                • 2012-11-16
                • 1970-01-01
                相关资源
                最近更新 更多