java - 枚举的枚举为 NULL

标签 java reference enums null

我正在为我的 Java 1.6 大学类(class)开发一个 LALG 编译器。所以我上了类型课和语法课。

枚举类型

public enum EnumTypes {

    A("OLA"),
    B("MUNDO"),
    C("HELLO"),
    D("WORLD"),

    /**
     * The order below is reversed on purpose.
     * Revert it and will you get a NULL list of types furder.
     */

    I(EnumGrammar.THREE),
    H(EnumGrammar.TWO),
    F(EnumGrammar.ONE),
    E(EnumGrammar.ZERO);

    private String strValue;
    private EnumGrammar enumGrammarValue;

    private EnumTypes(String strValue) {
        this.strValue = strValue;
    }

    private EnumTypes(EnumGrammar enumGrammarValue) {
        this.enumGrammarValue = enumGrammarValue;
    }

    public String getStrValue() {
        return strValue;
    }

    public EnumGrammar getEnumTiposValue() {
        return enumGrammarValue;
    }
}

枚举语法

public enum EnumGrammar {

    ZERO(EnumTypes.A,EnumTypes.B,EnumTypes.F,EnumTypes.D),
    ONE(EnumTypes.C),
    TWO(EnumTypes.B,EnumTypes.H),
    THREE(EnumTypes.D,EnumTypes.A,EnumTypes.C);

    private EnumTypes[] values;

    private EnumGrammar(EnumTypes ... values) {
        this.values = values;
    }

    public EnumTypes[] getValues() {
        return values;
    }
}

当我调用 EnumTypes.E.getEnumTiposValue().getValues() 时,EnumTypes.F 的值应该是 NULL .

主要

public class Main {

    public static void main(String[] args) {
        //prints [A, B, null, D]
        System.out.println(Arrays.toString(EnumTypes.E.getEnumTiposValue().getValues()));
    }

}

有解决方法或类似的方法吗?

谢谢!

最佳答案

本质上,在类完全构造之前,即在构造函数完成之前,允许对对象的引用离开类总是一件非常冒险的事情。枚举是单例。这里有两个类,它们的构造函数以循环依赖的方式接收彼此的实例。此外,类加载是惰性的,因此将加载类并创建枚举实例,最终结果取决于枚举的初始化顺序,这听起来很合理。

我现在无法从 JLS 中引用相应的点(我会寻找它),但我相信如果您允许对对象的引用从构造函数外部“离开类”(这会发生这里由于枚举是由 JVM 初始化的单例),JVM 可以自由地做一些奇怪的事情。

编辑:JLS 的这些要点对案例很重要:

  • 17.5.2 - 在构造该对象的线程中读取对象的最终字段是根据通常的先发生规则在构造函数中对该字段的初始化进行排序的。如果读取发生在构造函数中设置字段之后,它会看到最终字段分配的值,否则它会看到默认值。 由于枚举值在内部被视为静态最终字段(参见下面的 16.5),如果您从另一个枚举的构造函数内部引用一个枚举,而另一个枚举的构造函数引用第一个枚举,则这两个对象中至少有一个尚未完全初始化,因此此时引用可能仍为空。
  • 16.5 - 枚举常量的类主体中任何构造的明确赋值/取消赋值状态由类的通常规则控制
  • 8.3.2 - 字段初始化规则
  • 12.4.1 - 当初始化发生时

关于java - 枚举的枚举为 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38435168/

相关文章:

Swift 枚举不等式

java - Java 中的嵌套枚举

java - 循环遍历一个文件夹中存在的不同文件

javaFX - 创建流畅的动画而不创建新线程

android - 使用字符串而不是 ID 的引用控件

rust - Rust不能在hashmap中插入不同的结构

c++ - 引用可以指向 C++ 中的结构成员

grails - 在 Groovy 和 Grails 中使用枚举的正确方法

java - 在 joda time 如何在不更改时间的情况下转换时区

java - 使用 Cipher 程序对文本进行编码和解码