Java 循环枚举初始化 - 发生了什么以及为什么会发生?

标签 java static enums initialization

Possible Duplicate:
Java Enums: Two enum types, each containing references to each other?

在我们的代码中,我们遇到了一些与枚举有关的奇怪的 NPE。当我搜索时,我发现(或多或少)以下案例:

public class EnumTest {

  public static void main(final String[] args){
    System.out.println("------ START ----- ");
    System.out.println("BeezleBubs FOO's rockSteady is: " + BeezleBub.FOO.rockSteady);
    System.out.println("RockSteady BAR's beezleBub is: " + RockSteady.BAR.beezleBub);
    System.out.println("------  END  ----- ");
  }

  public enum RockSteady {
    BAR(BeezleBub.FOO);

    public final BeezleBub beezleBub;
    private RockSteady(final BeezleBub beezleBub) {
        this.beezleBub = beezleBub;
        System.out.println("Constructing RockSteady, beezleBub = " + beezleBub);
    }

  }

  public enum BeezleBub {

    FOO(RockSteady.BAR);

    public final RockSteady rockSteady;

    private BeezleBub(final RockSteady rockSteady) {
        this.rockSteady = rockSteady;
        System.out.println("Constructing BeezleBub, rockSteady = " + rockSteady);
    }

  }
}

由于某种原因,结果很尴尬。运行时,此测试输出:

------ START ----- 
Constructing RockSteady, beezleBub = null
Constructing BeezleBub, rockSteady = BAR
BeezleBubs FOO's rockSteady is: BAR
RockSteady BAR's beezleBub is: null
------  END  ----- 

另一件事是,当您切换调用枚举的 System.out.prinln() 语句时,枚举的初始化也会发生变化。结果是:

------ START ----- 
Constructing BeezleBub, rockSteady = null
Constructing RockSteady, beezleBub = FOO
RockSteady BAR's beezleBub is: FOO
BeezleBubs FOO's rockSteady is: null
------  END  ----- 

有人对发生的事情有清楚的解释吗?它与状态和秩序有关,但我不能完全确定它......

最佳答案

在 Java 中,类是延迟加载和初始化的。这意味着,无论您尝试首先打印哪个类的属性,都会先加载并初始化。一般来说,如果您有类的相互递归初始化程序,那么您应该避免在所有构造函数完成之前检查它们的属性。

原因很简单,Java 没有可以执行的初始化步骤序列来确保所有可能用途的原子初始化。

顺便说一句,这与枚举无关,它可能发生在普通的旧 Java 类中。

关于Java 循环枚举初始化 - 发生了什么以及为什么会发生?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8076534/

相关文章:

javax.ws.rs.NotFoundException : HTTP 404 Not Found angular 1. 5

swift - 在 switch 之外访问 swift 枚举案例?

java - 问 : Rental Car Calculator | Use a sentinel value loop

Android自定义 View : How to update custom enum attribute via LiveData & data binding

从 AnyHashable 快速转换为枚举

java - 如何部署基本的java应用程序

java - Android - 套接字超时

java - 如何在 Controller 中捕获 java.lang.NumberFormatException.forInputString 异常?

c++ - 在类或结构中调用静态函数的好习惯

java - 私有(private)类的静态最终成员初始化