一个枚举可以为每个常量有一个构造函数

请看这个链接。 Joshua Bloch在他的着作Effective Java中写道

请注意,操作常量从创建常量后运行的静态块放入stringToEnum映射中。

试图让每个常量都将 其自己的构造函数放入映射中会导致编译错误

。 这是一件好事,因为如果它合法的话会导致NullPointerException。

编译时常量字段外,枚举构造函数不允许访问枚举的静态 字段。

此限制是必需的,因为这些静态字段在构造函数运行时尚未初始化。

我有两个问题

  • 可以枚举每个常量具有单独的构造函数吗?
  • 为什么编译时常量字段在构造函数中可访问,但不是静态字段?
  • 谢谢


    至于第一个问题:你不能有单独的构造函数,但你可以通过以下方式来解决这个问题:

    public enum EnumTest {
        ONE() {
            void init() {
                val = 2;
            }
        },
        TWO() {
            void init() {
                val = 1;
            }
        };
    
        protected int val;
    
        abstract void init();
    
        EnumTest() {
            init();
        }
    }
    

    这样你在技术上对不同的常量有不同的初始化方法。

    另一种方法是使用初始化器部分:

    public enum EnumTest {
        ONE() {{
                val = 2;
            }},
        TWO() {{
                val = 1;
            }};
    
        protected int val;
    }
    

    至于你的第二个问题:在枚举构造期间不能访问常量字段,因为静态字段可以访问枚举常量。 例如,这段代码编译正确:

    public enum EnumTest {
        ONE, TWO;
    
        public static final String ONE_STRING = ONE.toString();
    }
    

    如果允许从构造函数中访问ONE_STRING,则可能会有无限的初始化循环或访问尚未初始化的枚举常量。


  • 不,我不认为这就是布洛克的意思,尽管它没有以最好的方式制定。 一个enum可以有构造函数,就像书中的enum Operation 。 布洛赫用“自己的构造函数”表示的意思是:当Operation符的构造函数为特定的常量运行时。

  • 这已经由你上面引用的内容回答了:

    此限制是必需的,因为这些静态字段在构造函数运行时尚未初始化。


  • 适用于构造函数的常规规则。 只要具有不同的签名,就可以拥有尽可能多的构造函数。 然后可以使用不同的构造函数构建不同的enum值:

    enum StringAndNumber {
        Zero("zero"),
        Five(5),
        Pi("Pi", 3.14159);
    
        private final String str;
        private final Number num;
    
        private StringAndNumber(String str) {
            this.str = str;
            this.num = null;
        }
    
        private StringAndNumber(Number num) {
            this.num = num;
            this.str = null;
        }       
    
        private StringAndNumber(String str, Number num) {
            this.str = str;
            this.num = num;
        }
    }
    
    链接地址: http://www.djcxy.com/p/38069.html

    上一篇: Can an enum have a constructors for each of its constants

    下一篇: Enum and static variable in constructor