java中禁止在类的构造函数中访问static
变量。enum
为什么在枚举中不交换静态初始化的顺序?
正确代码示例:
enum Test
{
TEST1, TEST2;
static int x;
}
为什么java的开发人员没有创建正确的代码:
enum Test
{
static int x;
TEST1, TEST2;
}
然后static
变量可以在构造函数中使用。现在是禁止的。
有什么原因还是只是他们的设计?
嗯,这是为了确保安全的实例初始化——枚举实例与枚举类的实例非常相似static final
,并且语言已经定义它们首先被初始化。
但是,如果您知道一两个技巧,则可以在枚举构造函数中有效地使用静态变量:
enum Test {
TEST1, TEST2;
static class Holder {
static int x;
}
Test() {
Holder.x++; // no compiler error
}
}
有关更多信息,请参阅按需初始化持有者习语
来自 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()
对构造函数和静态块的调用——你会看到构造函数首先被执行。