我遇到一个小问题:我开发了一个" ExampleQuest"我的游戏类扩展了抽象类Quest。我这样做是为了创建单独的任务类。现在我的ExampleQuest类应该计算我的实体的死亡,所以我实现了我的EntityListener。现在我必须在我的Playstate类中注册它以使一切正常但这是我的实际问题:方法 Playstate.addEntityListener(this)给了我一个nullpointer异常。我发现此错误是由任何扩展类引起的。如果ExampleQuest不会扩展Quest一切正常。我的Quest类没有任何错误,因为如果我用其他东西扩展ExampleQuest,我也会得到一个nullpointer异常。
--->所以我的解释是来自 Playstate.addEntityListener(this)的 this 引用了本例中的扩展类Quest而不是EntityListener。我怎样才能解决我的问题?
public class ExampleQuest extends Quest implements EntityListener {
public ExampleQuest() {
super();
Playstate.addEntityListener(this); //gives me nullointer exception
}
//implemented method
public void entityDeathEvent(EntityEvent e) {
}
}
这是我的Playstate课程的一部分:
public class Playstate {
public static Set<EntityListener> entityListener;
public Playstate() {
entityListener = new HashSet<EntityListener>();
}
public static void addEntityListener(EntityListener listener) {
entityListener.add(listener);
}
}
编辑:这是正常的:
public class EventHandler implements EntityListener {
public EventHandler() {
Playstate.addEntityListener(this);
}
}
它的工作原理是因为EventHandler 仅实现了一个类
答案 0 :(得分:1)
您的字段entityListener
为空,因为它是静态的,您只在创建Playstate
的对象时初始化字段。
可能entityListener
和addEntityListener
都不应该是静态的。让他们成为实例成员。
public class Playstate {
public Set<EntityListener> entityListener;
public Playstate() {
entityListener = new HashSet<EntityListener>();
}
public void addEntityListener(EntityListener listener) {
entityListener.add(listener);
}
}
关于您的修改:我们只能假设当您的EventHandler
代码运行时,它会起作用,因为您已在代码中的其他位置创建了Playstate
对象。< / p>
使用Playstate
的静态事件侦听器意味着所有此类对象将共享事件侦听器,这是一个&gt;可怕的&lt; 想法。真的,让他们成为实例成员,你会好多了。
答案 1 :(得分:1)
您获得NPE的原因是entityListener
尚未初始化。 entityListener
尚未初始化的原因是您的代码需要在开始使用Playstate
方法之前创建addEntityListener
的实例,但您调用addEntityListener
< em>在创建Playstate
的实例之前。
这是错误的: static 变量不应该在实例构造函数中初始化。你需要在声明中这样做,比如
public static Set<EntityListener> entityListener = new HashSet<EntityListener>();
或在static
初始化程序块中,如下所示:
public static Set<EntityListener> entityListener;
static {
entityListener = new HashSet<EntityListener>();
}
使entityListener
实例变量也可以工作,但是你需要提供一种从Playstate
的构造函数的上下文中获取ExampleQuest
实例的方法。
答案 2 :(得分:0)
public Playstate() {
entityListener = new HashSet<EntityListener>();
}
public static void addEntityListener(EntityListener listener) {
entityListener.add(listener);
}
在构造PlayState构造函数时,为entityListener static 变量赋值。这是一个严重的设计问题:侦听器是静态的,因此不与任何PlayState实例相关联,因此每次创建实例时都不应该分配,或者它与给定实例相关联,并且它不应该是静态的。
侦听器和addEntityListener()
方法不应该是静态的。相反,任务应该引用PlayState类的实例。
此外,由于它是一组侦听器,因此该变量应命名为entityListeners
,而不是entityListener
。