Java 枚举中的空指针异常

Null Pointer Exception in Java Enum

我正在 java 学习枚举概念,但在练习时遇到了问题。

这是代码片段,

public class MyClass {
    private String cardColor = CARDS.SPADE.cardColor; #Causes Null Pointer #Default Value
    private MyClass(CARDS card){
        this.cardColor = card.cardColor;
    }
    public static enum CARDS{
        SPADE("Black"),
        CLUB("Black"),
        DIAMOND("Red"),
        HEART("Red");
        private String cardColor = null;
        private MyClass obj = null;
        CARDS(String color){
            this.cardColor = color;
            obj = new MyClass(this);         #Trying to create object for MyClass 
        }
        public String getCardColor(){
            return this.cardColor;
        }
    }
    public static void main(String args[]) {
        System.out.println(CARDS.SPADE);
    }
}

我正在尝试在其构造函数中创建枚举私有的 MyClass 对象。这里的值 CARDS.SPADE 为空,我最终得到空指针异常。

如果我不在枚举构造函数中创建对象,一切都会完美无缺,

obj = new MyClass(this);

我不明白为什么静态枚举没有初始化,我对这里的控制流感到困惑。谁能给我解释一下这是怎么回事?

你有一个循环依赖:CARDS 枚举的初始化和 MyClass 实例相互依赖。
CARDS 构造函数实例化 MyClassMyClass 构造函数依赖于 CARDS.SPADE 状态,该状态尚未像挂起的枚举构造函数中那样完全初始化。

要么打破这个循环,要么分两次做。在没有双向关系的情况下初始化枚举,并在调用构造函数后,通过 setter 将枚举值设置为 MyClass 实例。

请注意,NullPointerException 的 "real" 原因是您没有引用在枚举构造函数 (this) 中创建的当前实例,而是引用了枚举值来自枚举 class 本身:MyClass.CARD.SPADE.
第一个有状态,但第二个还没有,因为枚举构造函数尚未返回。

通过将枚举实例传递给 MyClass 的构造函数,它将 "work" :

CARDS(String color){
        this.cardColor = color;
        obj = new MyClass(this);    
    }
}

// ...
public MyClass(CARDS cards){
     cardColor = cards.cardColor;
}

但一般来说,在构造函数主体期间将 this 传递给另一个 object/class 不是一个好主意。如果对象状态在此时和构造函数调用结束之间发生变化,这 可能 泄漏到不一致的状态。