【问题标题】:Enum - static initialization order [duplicate]枚举 - 静态初始化顺序 [重复]
【发布时间】:2013-10-29 07:59:58
【问题描述】:

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

正确代码示例:

enum Test
{
    TEST1, TEST2;

    static int x;
}

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

enum Test
{
    static int x;

    TEST1, TEST2;
}

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

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

【问题讨论】:

  • "在 Java 中禁止访问静态变量" - 这是什么意思?
  • @PM77-1 见编辑。句子不清楚。
  • @JamesMontagne 我知道为什么 static 变量不能在 costructor 中使用。我想知道为什么java的开发者和架构师没有改变初始化的顺序。
  • 在那种情况下,我可能会认为这个问题“主要基于意见”meta.stackexchange.com/questions/10582/…
  • 如果有原因,那么它不是基于意见的。如果没有原因,答案是:“没有原因,只是他们的设计”,话题可以关闭了。

标签: java enums


【解决方案1】:

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

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

enum Test {
    TEST1, TEST2;

    static class Holder {
        static int x;
    }

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

欲了解更多信息,请参阅Initialization-on-demand holder idiom

【讨论】:

  • 好的,但是如果 TEST1TEST2 的初始化将在课程结束时移动,那么我们就不必做任何技巧了。我想知道为什么初始化顺序是这样的。
【解决方案2】:

来自 JLS (§8.9):

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


枚举声明: ClassModifiersopt enum Identifier Interfacesopt 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() 调用添加到构造函数和静态块 - 您会看到构造函数首先被执行。

【讨论】:

  • OP 知道这一点。问题是为什么要这样设计。
  • 没错。我知道构造,我想知道构造的原因,因为我的第二构造也是正确的(不是编译器编译的,但可以执行)。
  • @Pshemo OP 询问“它有什么原因还是只是他们的设计?”,我的回答告诉他,它的设计目的是为了以这种方式工作。至于“为什么”的哲学原因,他将不得不问 Gosling,但一个很好的猜测是因为 Enum initialization rules 与“普通”类不同(即静态初始化程序与构造函数) - 它只是让决定一个有意义的顺序。
猜你喜欢
  • 1970-01-01
  • 2015-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-12
  • 1970-01-01
  • 2014-06-01
相关资源
最近更新 更多