这与枚举和类初始化有关。
首先,
enum只是
class具有恒定字段的幻想。也就是说,您声明的枚举常量实际上只是
static字段。所以
enum SomeEnum { CONSTANT;}编译成类似于
final class SomeEnum extends Enum<SomeEnum> { public static final SomeEnum ConSTANT = new SomeEnum();}其次,
static字段以从左到右的顺序初始化,它们出现在源代码中。
接下来,以文本顺序执行类的类变量初始化器和静态初始化器,或接口的字段初始化器,就好像它们是单个块一样。
在下面的
final class SomeEnum extends Enum<SomeEnum> { public static final SomeEnum ConSTANT = new SomeEnum(); public static final SomeEnum CONSTANT_2 = new SomeEnum();}CONSTANT将首先被初始化,然后被初始化
CONSTANT_2。
第三,当您访问类型的常量之一(实际上只是一个字段)时,该
enum类型将被[初始化]
[3]
static。
第四,如果当前线程正在初始化一个类,则可以正常进行。
如果
Class对象C表示C当前线程正在进行初始化,则这必须是对初始化的递归请求。释放LC并正常完成。
这一切如何融合在一起?
这个
ENUM.ANIMALS.CATS.GARFIELD.RIVAL
被评估为
CATS cat = ENUM.ANIMALS.CATS.GARFIELD;DOGS rvial = cat.RIVAL;
首次访问将
GARFIELD强制
enum类型的初始化
CATS。这开始初始化中的枚举常量
CATS。编译后,这些看起来像
private static final CATS FELIX = new CATS(DOGS.AKAME);private static final CATS GARFIELD = new CATS(DOGS.WEED);private static final CATS BUBSY = new CATS(DOGS.GIN);
这些按顺序初始化。所以
FELIX先去。作为其新实例创建表达式的一部分,它访问
DOGS.AKAME,而该类型
DOGS尚未初始化,因此Java开始对其进行初始化。该
DOGS枚举类型,编译,看起来像
private static final DOGS GIN = new DOGS(CATS.FELIX);private static final DOGS WEED = new DOGS(CATS.BUBSY);private static final DOGS AKAME = new DOGS(CATS.GARFIELD);
因此,我们从开始
GIN。在其新的实例创建表达式中,它尝试访问
CATS.FELIX。
CATS当前正在初始化,因此我们继续。
CATS.FELIX尚未分配值。目前,它在堆栈中的位置较低。因此其值为
null。因此
GIN.RIVALS获得对的引用
null。同样的情况,给所有
DOGS“
RIVAL。
DOGS初始化所有后,执行返回
private static final CATS FELIX = new CATS(DOGS.AKAME);
其中,
DOGS.AKAME现指完全初始化
DOGS的对象。那被分配给它的
CATS#RIVAL领域。每个都相同
CATS。换句话说,所有的
CATS‘
RIVAL字段都被分配了一个
DOGS引用,但是没有相反的方式。
对语句重新排序只是确定
enum首先要初始化的类型。



