Java枚举中的空指针异常

时间:2019-06-19 06:11:51

标签: java enums enumeration

我正在学习Java中的Enum概念,并且在练习时遇到问题。

这是代码段,

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为null,最后我得到Null Pointer Exception。

如果我没有在枚举构造函数中创建对象,那么一切正常,

  

obj = new MyClass(this);

我不明白为什么静态枚举未初始化,并且我对这里的控制流程感到困惑。有人可以告诉我这是怎么回事吗?

1 个答案:

答案 0 :(得分:1)

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

要么中断此循环,要么两次执行操作。初始化没有双向关系的枚举,并在构造函数调用之后,通过设置器将枚举值设置为MyClass实例。

请注意,NullPointerException的“真正”原因是您没有引用在enum构造函数(this)中创建的当前实例,而是从enum类引用了enum值。本身:MyClass.CARD.SPADE
第一个有状态,但是第二个还没有,因为枚举构造函数还没有返回。

通过将枚举实例传递到MyClass的构造函数中,它将“起作用”:

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

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

但是通常,在构造函数主体中将this传递给另一个对象/类不是一个好主意。如果对象状态在此时间和构造函数调用结束之间发生更改,则此 可能泄漏为不一致状态。