【问题标题】:What's difference between enums and final variables? [duplicate]枚举和最终变量有什么区别? [复制]
【发布时间】:2013-12-18 15:25:36
【问题描述】:

我正在尝试阅读枚举以更好地理解它们。

从枚举的 javadocs 我得到以下信息:

枚举类型是一种特殊的数据类型,它使变量成为一组预定义的常量。

对我来说,这听起来很像 final 变量。

  1. 真正的区别是什么?
  2. 您什么时候会使用其中一种?
  3. 枚举只是可以是一组事物的最终变量吗?

【问题讨论】:

标签: java enums


【解决方案1】:

不同之处在于枚举提供类型安全

让我们拥有这个enum

public enum MuEnum {
    FIRST("First"), SECOND("Second");

    private String value;

    MyEnum(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}

考虑以下示例:

public void myMethod(MyEnum parameter) { .. }

在这里,您只能传递 MyEnum 值(FIRSTSECOND),而如果您的方法签名是:

public void myMethod(String parameter) { .. }

您将能够传递无效参数(某些 String 的内容不同于 "First""Second")。

【讨论】:

    【解决方案2】:

    当你有一个enum 喜欢时

    public enum MyEnum {
       FIRST_COSTANT, SECOND_CONSTANT;
    }
    

    你真正拥有的是

    public class /* enum */ MyEnum extends Enum<MyEnum> {
        private Enum() {}
        public final static MyEnum FIRST_CONSTANT = new MyEnum() {};
        public final static MyEnum SECOND_CONSTANT = new MyEnum() {};    
        ... // methods     
    }
    

    所以从这个意义上说,是的,它们是相同的。

    Java 语言规范here 对此进行了解释。

    除了枚举类型 E 继承自 Enum 的成员之外, 对于每个声明的名为 n 的枚举常量,枚举类型都有一个 隐式声明的公共静态最终字段,名为 n,类型为 E。这些 字段被视为以与 相应的枚举常量,在任何静态字段显式之前 在枚举类型中声明。每个这样的字段都初始化为枚举 与之对应的常数。每个这样的字段也被认为是 使用与相应枚举相同的注解进行注解 持续的。枚举常量据说是在 相应的字段被初始化。

    【讨论】:

    • 每个枚举条目都是一个子类,而不是一个实例
    【解决方案3】:

    有一个很大的区别:首先,enum,不是变量,是类型。一个final 变量,比如一个int,可以在int 的许多可能值中具有单个预设值,而enum 变量(也可以是final)可以具有以下值定义 enum 时声明的集合。

    这是一个例子:

    enum Color {Red, Green, Blue;}
    

    上面的声明没有定义变量。它定义了一组值 Color 类型的变量可以拥有,如果你选择声明一个:

    Color backgroundColor = Color.Red;
    

    现在你有一个枚举类型的非最终变量Color。它的值可以改变,但它必须是定义为enum 一部分的三个值之一。

    在实践中,当您对具有固定数量状态的事物进行建模时,您会使用enum,并为其命名。您也可以为此使用一个或多个 final 变量 - 事实上,在引入 enums 之前,这已经做了很多。例如,Java 的 Calendar 类对日期的各个部分使用 static final int 常量,而 enum 会更好。

    【讨论】:

      【解决方案4】:

      我认为枚举不是最终的,因为您可以为枚举描述符中的每个字段定义一个匿名子类。

      来自文档:

      枚举类型(第 8.9 节)不得声明为抽象的;这样做会导致 在编译时错误中。

      一个枚举类型是隐式最终的,除非它包含至少一个枚举 具有类主体的常量。

      显式声明枚举类型为编译时错误 最后。

      嵌套枚举类型是隐式静态的。是允许的 将嵌套枚举类型显式声明为静态。

      还要标记一点,如果我们说一个类为 Final 则意味着它们不能被继承。但是,当涉及到枚举时,默认情况下它们不能被继承。

      【讨论】:

        【解决方案5】:

        在一种思维方式中,是的。以下语句大致等价:

        // This...
        final int FIRST = 0;
        final int SECOND = 1;
        
        // Is roughly equivalent to this.
        enum Ordering = { FIRST, SECOND };
        

        区别在于类型安全。由于Ordering 枚举命名了一个新类型,因此您可以拥有一个采用Ordering 而不是int 的函数。这可确保在编译时您不会意外地将越界值(如 2)传递给期望 Ordering 的函数。

        void foo(Ordering order) {;}
        
        foo(FIRST); // This works
        foo(3); // This causes an error at compile time
        

        【讨论】:

          【解决方案6】:

          枚举用于您知道将拥有多少个类型实例的每种情况。是的,在枚举之前,使用了静态最终变量。

          Enums 提供了一些简单的静态最终变量所没有的细节:

          • 它们是打字的。
          • 它们带有一些有用的方法,例如 valueOf,允许按名称查找它们或枚举它们。
          • 每个实例都可以覆盖枚举的方法以提供特定的行为。
          • Enum 确保不会有任何其他类的实例而不是定义的实例,而不必将构造函数设置为私有或其他可以通过反射克服的技巧。因此,这是实现一些模式(如 Singleton 模式)的好方法。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-11-26
            • 2015-08-13
            • 2018-09-25
            • 1970-01-01
            • 1970-01-01
            • 2016-06-13
            相关资源
            最近更新 更多