java中禁止访问enum
类的构造函数中的static
变量。为什么在枚举中不交换静态初始化的顺序?
正确代码示例:
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):
枚举声明指定新的枚举类型
枚举声明: ClassModifiersopt enum Identifier Interfacesopt EnumBody
EnumBody: { EnumConstants-opt ,opt EnumBodyDeclarations-opt }
如您所见,主体应该首先声明枚举常量来定义,其他主体声明可能会随之而来 - 而不是相反!
此外,您不必像波西米亚建议的那样使用延迟初始化,您可以以更简单的方式进行初始化。根据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()
调用 - 您将看到构造函数首先被执行。