我正在学习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);
我不明白为什么静态枚举未初始化,并且我对这里的控制流程感到困惑。有人可以告诉我这是怎么回事吗?
答案 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
传递给另一个对象/类不是一个好主意。如果对象状态在此时间和构造函数调用结束之间发生更改,则此 可能泄漏为不一致状态。