3

java中禁止在类的构造函数中访问static变量。enum为什么在枚举中不交换静态初始化的顺序?

正确代码示例:

enum Test
{
    TEST1, TEST2;

    static int x;
}

为什么java的开发人员没有创建正确的代码:

enum Test
{
    static int x;

    TEST1, TEST2;
}

然后static变量可以在构造函数中使用。现在是禁止的。

有什么原因还是只是他们的设计?

4

2 回答 2

5

嗯,这是为了确保安全的实例初始化——枚举实例与枚举类的实例非常相似static final,并且语言已经定义它们首先被初始化。

但是,如果您知道一两个技巧,则可以在枚举构造函数中有效地使用静态变量:

enum Test {
    TEST1, TEST2;

    static class Holder {
        static int x;
    }

    Test() {
        Holder.x++; // no compiler error
    }
}

有关更多信息,请参阅按需初始化持有者习语

于 2013-10-20T23:40:25.760 回答
1

来自 JLS (§8.9)

枚举声明指定了一个新的枚举类型


EnumDeclaration: ClassModifiersopt enum Identifier Interfacesopt EnumBody

EnumBody: { EnumConstants-opt ,opt EnumBodyDeclarations-opt }


正如你所看到的,body 应该使用首先声明的 enum-constants 来定义,然后可能会跟随其他 body 声明——而不是相反!

此外,您不必像波西米亚那样使用延迟初始化,建议您可以以更简单的方式进行。根据 JLS,你不能这样做:

enum Test {
    TEST1, TEST2;
    static int x;

    Test(){
        x = 1; // <-- compilation error!
    }
}

但您可以使用静态初始化程序块:

enum Test {
    TEST1, TEST2;
    static int x;

    static{
        x = 1; // works!
    }
}

您可以使用后者的原因是静态声明以它们声明的相同顺序执行 - 分配x=1只会在x声明之后发生,这与使用构造函数不同。如果你想验证它——你可以添加System.out.println()对构造函数和静态块的调用——你会看到构造函数首先被执行。

于 2013-10-20T23:50:17.047 回答