【问题标题】:illegal reference to static field from initializer从初始化程序非法引用静态字段
【发布时间】:2015-05-24 07:46:07
【问题描述】:

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

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? 这里问的问题与我问的完全相反。在我的情况下,将 s 声明为静态编译代码就好了。

【问题讨论】:

  • 看过了,看不懂,一点都不清楚
  • 实例字段不能引用枚举级别的静态字段。如果可能的话,你打算用什么变量 s?
  • @tinker 但是为什么不能在这里引用静态字段:class X { static X x; Xy=x; }

标签: java class oop enums static


【解决方案1】:

考虑以下示例:

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 被初始化为正确的值时将被执行。

【讨论】:

    【解决方案2】:

    想想这样的枚举:

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

    【讨论】:

    • 谢谢你,Richard。是的现在很有意义。非常感谢你为我倾倒它!干杯!
    【解决方案3】:

    来自Java Language Specification

    引用枚举类型的静态字段是编译时错误 这不是来自构造函数的常量变量(第 4.12.4 节),实例 初始化块,或实例变量初始化表达式 那种类型。

    【讨论】:

    • @user3678484 考虑接受最适合您的答案(如果有的话)
    【解决方案4】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 2018-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多