我是java中enums的新手,我很困惑为什么这段代码编译得很好
enum Scale5 {
GOOD(), BETTER(), BEST();
static Scale5 s=GOOD;
}
但是这段代码失败了:
enum Scale5 {
GOOD(), BETTER(), BEST();
Scale5 s=GOOD;
}
我收到错误:非法引用初始化程序中的静态字段。 我不明白这个原因。我在枚举方面相对缺乏经验,所以请把它转发给我。谢谢你们!谢谢!
这里提出的问题Cannot refer to the static enum field within an initializer?与我提出的问题正好相反。在我的情况下,声明静态编译代码就好了。
答案 0 :(得分:5)
来自Java Language Specification:
引用枚举类型的静态字段是编译时错误 这不是构造函数实例的常量变量(第4.12.4节) 初始化块或实例变量初始化表达式 那种类型。
答案 1 :(得分:3)
想想这样的枚举:
public final class Scale5
{
public static final Scale5 GOOD = new Scale5();
public static final Scale5 BETTER = new Scale5();
public static final Scale5 BEST = new Scale5();
static Scale5 s = GOOD;//works because GOOD is initialized first;
Scale5 ss = GOOD;//doesn't work because in order to initialize GOOD,
//ss must be assigned an object that is not yet initialized;
}
答案 2 :(得分:1)
很简单。第一种情况有效,因为编译器定义了所有枚举常量,然后初始化静态变量。因此,那时的GOOD已经存在并且一切都很好。
在第二种情况下,变量存在于所有枚举常量中,因此,当您创建GOOD(或更好或最好)时,必须已经定义和绑定GOOD。这当然是非法的。
答案 3 :(得分:0)
请考虑以下示例:
class X {
public static final X GOOD = new X();
X y = GOOD;
static X z = GOOD;
public static void main(String[] args) {
System.out.println(GOOD);
System.out.println(GOOD.y);
System.out.println(X.z);
}
}
输出:
X@1db9742
null
X@1db9742
正如您所看到的,GOOD.y
的价值是null
。那是因为在初始化
public static final X GOOD = new X();
当您调用new X()
时,使用GOOD
的当前值null
,直到new X()
完成为止。虽然在普通类的情况下允许这种行为,但是它被禁止用于枚举,可能是因为它经常被误解。
在静态字段的情况下,它们被执行问题消散器,因为它们是按声明的顺序执行的,所以
static X z = GOOD;
当我们确定GOOD
已使用适当的值进行初始化时,将执行。