为什么枚举构造函数不能访问静态字段

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

enum Test {
  e1,e2;      

  int i=0;
  static int j=5;

  Test(){
    System.out.println(i+" "+j);
  }
}

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

我已经阅读了与其他作者有关的答案,都说e1和e2在J(静态字段)的初始化之前被初始化了,但是根据Java规范,所有的静态字段都会在类加载到内存时初始化,也就是在运行之前构造函数。 所以在运行Test()构造函数之前,必须初始化静态变量j。 我无法理解限制,任何机构都可以让我理解。我已经阅读过这些问题的答案为什么无法枚举的构造函数访问静态字段? 但我并不满意于这样的回答: - 在静态字段全部被初始化之前调用构造函数。

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

class Test{
  public static final Test t=new Test();
  static int a=5;

  Test(){
    System.out.println(a);  
  }

  public static void main(String[] args) {
  }
}

这里根据这个参数,构造函数将在静态字段的初始化之前运行,并且它也会在print 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的构造函数不能访问静态字段?”所述,它不幸的是,这发生在所有用户定义的静态字段初始化之前。 但是如果它被交换了,你不能在静态初始化中访问枚举实例,所以它需要在创建枚举值之前和之后都允许静态块。

我不知道是否问题是因为enum值的官方化是Enum类的关注(并且由JVM处理(这种逻辑不在Enum类本身中),或者因为您无法在枚举值之前放置静态字段。

为什么这种方式只能回答很少的人(例如Josh Bloch和Neal Gafter,他们是javadoc中的Enum的作者,也可能是一些未知的人)

链接地址: http://www.djcxy.com/p/38063.html

上一篇: Why enum constructor can't access static field

下一篇: Are there any guarantees in JLS about order of execution static initialization blocks?