从初始化程序非法引用静态字段

时间:2015-03-20 19:23:26

标签: java class oop enums static

我是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?与我提出的问题正好相反。在我的情况下,声明静态编译代码就好了。

4 个答案:

答案 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已使用适当的值进行初始化时,将执行