【问题标题】:enum properties & side effects枚举属性和副作用
【发布时间】:2013-12-03 07:07:33
【问题描述】:

我有一个关于枚举的问题(它可能是一个简单的问题,但是......)。 这是我的程序:

public class Hello { 
         public enum MyEnum 
         { 
               ONE(1), TWO(2); 
               private int value; 
               private MyEnum(int value) 
               { 
                    System.out.println("hello");  
                    this.value = value; 
               } 
               public int getValue() 
               { 
                    return value; 
               } 
        } 
        public static void main(String[] args)  
        { 
              MyEnum e = MyEnum.ONE; 
        } 
}

我的问题是:为什么输出是

hello
hello

而不是

hello ?

代码如何“去”两次到构造函数? 第一次是什么时候,第二次是什么时候? 为什么枚举构造函数不能公开? 这是它打印两次而不是一次的原因吗?

【问题讨论】:

  • 更改为 System.out.println("hello" + value );那么你就清楚了
  • 您还会注意到,像在 main() 中那样声明枚举实例没有任何效果。注释掉该行,构造函数仍然会运行两次。
  • 想想你为什么写 ONE(1),而不是 ONE("one") 或 ONE()?

标签: java enums


【解决方案1】:

枚举是单例,它们在加载类时被实例化 - 所以两个“hello”来自实例化 MyEnum.ONEMyEnum.TWO(也可以尝试打印 value)。

这也是构造函数不能公开的原因:Enum 保证每个值永远只有一个实例 - 如果其他人可以摆弄构造函数,它就不能这样做。

【讨论】:

  • 枚举类比单例模式(en.wikipedia.org/wiki/Multiton_pattern)更慢。正如 piet.t 所提到的,将枚举的构造函数公开是没有意义的,因为您不能直接创建枚举的新实例。枚举也自动是“静态的”并且在某种程度上是“最终的”。在您的情况下,“MyEnum”类绝对是“final”。但是,如果你向它添加抽象方法(是的,枚举可以有抽象方法)或在一个或两个中覆盖“getValue”,它在技术上不会是“最终的”:编译器将生成额外的类,继承自“MyEnum”。
【解决方案2】:

代码如何“去”两次到构造函数?

为枚举的每个元素调用构造函数。稍微改变你的例子来演示它:

public class Hello { 
    public enum MyEnum { 
        ONE(1), TWO(2); 
        private int value; 
        private MyEnum(int value) { 
            this.value = value;
            System.out.println("hello "+this.value);  
        } 
        public int getValue() { 
            return value; 
        } 
    } 
    public static void main(String[] args) { 
        MyEnum e = MyEnum.ONE; 
    } 
}

输出:

hello 1
hello 2

【讨论】:

    【解决方案3】:

    您的构造函数调用了两次。加载Enum 类的那一刻,它将调用等于enum 类型数量的时间。

     MyEnum e = MyEnum.ONE; // singleton instance of Enum
    

    考虑关注

    public class Hello {
    
    public enum MyEnum
    {
        ONE(1), TWO(2), THREE(3);
        private int value;
        private MyEnum(int value)
        {
            System.out.println("hello"+value);
            this.value = value;
        }
        public int getValue()
        {
            return value;
        }
    }
    public static void main(String[] args)
    {
        MyEnum e = MyEnum.ONE;
    }
    

    }

    输出

    hello1
    hello2
    hello3
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多