为什么枚举构造函数无法访问静态字段

可能重复:
为什么enum的构造函数不能访问静态字段?

enum Test { e1,e2; int i=0; static int j=5; Test(){ System.out.println(i+" "+j); } } 

在上面的代码中,构造函数可以访问实例变量但不能访问静态变量J.

我已经阅读了与其他作者有关的答案,所有人都说在初始化J(静态字段)之前初始化了e1和e2,但是根据java规范所有的静态字段在类加载到内存时初始化,也就是在运行之前构造函数。 因此,在运行Test()构造函数之前,必须初始化静态变量j。 我无法理解限制,任何机构都可以让我理解。我已经阅读了问题的答案为什么enum的构造函数不能访问静态字段? 但我对以下答案感到不满: – 在静态字段全部初始化之前调用构造函数。

假设如果使用像枚举这样的简单类的另一个例子

 class Test{ public static final Test t=new Test(); static int a=5; Test(){ System.out.println(a); } public static void main(String[] args) { } } 

根据那里的参数,构造函数将在静态字段初始化之前运行,并且它也在运行时打印0(因为JVM执行了初始化)。 但没有编译错误或没有运行时问题。 那么为什么同样的事情不会发生在枚举上。

如果你想象你的枚举实际上看起来像一个类,它是有道理的:

 public class Test { // Imagine you cannot move these two statements: public static final Test e1 = new Test(); public static final Test e2 = new Test(); int i=0; static int j=5; private Test(){ System.out.println(i+ " " + j); } static int getJ() { return j; } public static void main(String[] args) { System.out.println(Test.getJ()); } } 

这打印:

 0 0 0 0 5 

如果你可以分享一个具体的例子(而不是理论上的例子),我们可以建议如何重新设计代码以实现期望的结果,尽管静态字段限制。

问题是,枚举的实例是在静态字段的实际化过程中创建的。 他们在静态字段初始化之前创建。 它们必须是静态数组值并且可以静态访问,因此它是有意义的。 正如anser中所说的“为什么enum的构造函数不能访问静态字段?”,不幸的是,这发生在所有用户定义的静态字段inicialization之前。 但如果它被交换,则无法在静态初始化中访问枚举实例,因此在创建枚举值之前和之后都需要允许静态块。

我不知道问题是否是因为枚举值的内在化是Enum类的关注(并且由JVM专门处理(这个逻辑不在Enum类本身中),或者因为你不能在枚举值之前放置静态字段。

为什么这样才能回答很少的人(例如Josh Bloch和Neal Gafter,他们在javadoc中被称为Enum的作者,也许还有一些不为人知的人)