enum Test {
e1,e2;
int i=0;
static int j=5;
Test(){
System.out.println(i+" "+j);
}
}
在上面的代码中,构造函数可以访问实例变量,但不能访问静态变量J.
我已经阅读了与其他作者有关的答案,所有人都说e1和e2在J(静态字段)初始化之前初始化,但是根据java规范所有的静态字段 当类加载到内存时,即在运行构造函数之前初始化。 因此,在运行Test()构造函数之前,必须初始化静态变量j。我无法理解限制,任何机构都能让我理解。我已经阅读了问题的答案Why can't enum's constructor access static fields?但我对答案不满意如下: - 构造函数在静态字段全部被调用之前被调用已初始化。
假设用另一个像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进行了初始化)。但没有编译错误或没有运行时问题。那么为什么枚举不会发生同样的事情。
答案 0 :(得分:6)
如果你想象你的枚举实际上看起来像一个类,那就有意义了:
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
如果你可以分享一个具体的例子(而不是理论上的例子),我们可以建议如何重新设计代码以实现所需的结果,尽管存在静态字段限制。
答案 1 :(得分:2)
问题是,枚举的实例是在静态字段的实际化过程中创建的。他们在静态字段初始化之前创建。 它们必须是静态数组值并且可以静态访问,因此它是有意义的。正如anser to"为什么不能使用构造函数访问静态字段?",不幸的是,这发生在所有用户定义的静态字段inicialization之前。 但如果它被交换,则无法在静态初始化中访问枚举实例,因此在创建枚举值之前和之后都需要允许静态块。
我不知道问题是因为枚举值的内在化是Enum类的关注(并且由JVM专门处理(这个逻辑不在Enum类本身中),或者因为你不能在枚举值之前放置静态字段
为什么这样才能回答很少的人(例如Josh Bloch和Neal Gafter在javadoc中被称为Enum的作者,也许还有一些不为人知的人)