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

Ank*_*kit 7 java enums constructor effective-java

请看这个链接.Joshua Bloch在其着作"有效Java"一书中说

请注意,Operation常量将从创建常量后运行的静态块放入stringToEnum映射中.

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

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

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

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

我有两个问题

  1. 枚举可以为每个常量都有单独的构造函数吗?
  2. 为什么在构造函数中可以访问编译时常量字段而不是静态字段?

谢谢

Tag*_*eev 5

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

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

    protected int val;

    abstract void init();

    EnumTest() {
        init();
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,从技术上讲,您可以为不同的常量分别使用初始化方法.

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

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

    protected int val;
}
Run Code Online (Sandbox Code Playgroud)

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

public enum EnumTest {
    ONE, TWO;

    public static final String ONE_STRING = ONE.toString();
}
Run Code Online (Sandbox Code Playgroud)

如果允许从构造函数访问ONE_STRING,那么您将拥有无限的初始化循环或访问尚未初始化的枚举常量.