Java - 参考已实现的类

时间:2015-07-08 19:15:41

标签: java reference implementation

我遇到一个小问题:我开发了一个" 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 实现了一个类

3 个答案:

答案 0 :(得分:1)

您的字段entityListener为空,因为它是静态的,您只在创建Playstate的对象时初始化字段。

可能entityListeneraddEntityListener都不应该是静态的。让他们成为实例成员。

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