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

illegal reference to static field from initializer

我是 java 中枚举的新手,我很困惑为什么这段代码编译得很好

enum Scale5 {
GOOD(), BETTER(), BEST();
static  Scale5 s=GOOD;
}

但是这段代码失败了:

enum Scale5 {
GOOD(), BETTER(), BEST();
Scale5 s=GOOD;
}

我收到错误:初始化程序对静态字段的非法引用。 我不明白 reason.I 我在枚举方面相对缺乏经验,所以请把它丢给 me.Thanks 很多!

这里问的问题 Cannot refer to the static enum field within an initializer? 与我的完全相反 asked.In 我的案例将 s 声明为 static 可以很好地编译代码。

很简单。第一种情况有效,因为编译器定义了所有枚举常量,然后初始化静态变量。因此,此时的 GOOD 已经存在,一切都很好。

在第二种情况下,所有枚举常量都存在变量,因此,当您创建 GOOD(或 BETTER 或 BEST)时,必须已经定义和绑定 GOOD。这当然是违法的。

来自Java Language Specification

It is a compile-time error to reference a static field of an enum type that is not a constant variable (§4.12.4) from constructors, instance initializer blocks, or instance variable initializer expressions of that type.

想像这样的枚举:

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;
}

考虑以下示例:

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 已使用正确的值初始化时执行。