Java枚举中的静态(和最终)字段初始化

Tho*_*sin 2 java enums static final initialization

假设我具有以下列举的颜色类型:

public enum Colour
{
    RED, GREEN, BLUE;
}
Run Code Online (Sandbox Code Playgroud)

我想根据那边的建议从这三种颜色中随机分配一种颜色:https : //stackoverflow.com/a/8114214/2736228

但是我不想values()一遍又一遍地打电话,所以,我想到了以下内容:

public enum Colour
{
    RED, GREEN, BLUE;

    private static final Colour[] Values = values();

    public static Colour random()
    {
        return Values[(int) (Math.random() * Values.length)];
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,它将始终有效吗?

让我感到困惑的是,何时初始化此private static final字段。它应该在完整的枚举列表完成之后发生。我看不到它会很快发生,但是我还是要确定。

rge*_*man 5

是的,此初始化将始终有效。枚举常量始终列在最前面,并且JLS(第8.9.3节)保证将在任何其他普通static变量之前对其进行初始化。

对于E声明主体中声明的每个枚举常量c,E都有一个隐式声明的E类型的公共静态最终字段,该字段与c具有相同的名称。该字段具有一个由c组成的变量初始值设定项,并由与c相同的批注进行批注。

在E声明的主体中显式声明的任何静态字段之前,以与相应的枚举常量相同的顺序隐式声明这些字段。

所有static字段都按顺序初始化,就好像它们是单个文本块一样,因此在Values调用初始化之前,所有枚举常量都将被初始化values()

顺便提一句,static final变量通常用所有大写字母命名,例如VALUES,按照标准Java命名约定。