Java Singleton NullPointerException

问题描述 投票:1回答:2

我正在从头开始用Java构建我的第一个游戏。我已经决定GameWorld类集中了游戏的主要操作(处理输入等),最好实现为单例(使用枚举)。枚举的相关代码如下。

public enum GameWorld {
    INSTANCE;
    private static InputController input = InputController.getInput();
    public EntityPlayer player = new EntityPlayer(10, 10, 5, 5);

    public static GameWorld getWorld() {
        return INSTANCE;
    }

    public InputController getInputController() {
        return input;
    }
}

EntityPlayer的构造函数中发生异常。代码和堆栈跟踪如下。

public class EntityPlayer implements Entity, InputListener {
    private int xPos;
    private int yPos;
    private int width;
    private int height;

    // Velocity of object
    // Determines where it sets itself on update
    private int xVel;
    private int yVel;
    private GameWorld world;

    private InputController input;

    private boolean solid;

    public EntityPlayer(int x, int y, int width, int height) {
        xPos = x;
        yPos = y;
        this.width = width;
        this.height = height;
        solid = true;
        xVel = 0;
        yVel = 0;
        world = getWorld();
        input = world.getInputController();
        input.registerKeyListener(this);
    }

    @Override
    public Graphics draw(Graphics g) {
        g.setColor(Color.yellow);
        g.fillRect(xPos, yPos - height, width, height);
        return g;
    }

    @Override
    public void update() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getXPos() {
        return xPos;
    }

    @Override
    public int getYPos() {
        return yPos;
    }

    @Override
    public Rectangle getRect() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public boolean isSolid() {
        return solid;
    }

    @Override
    public void kill() {

    }

    @Override
    public GameWorld getWorld() {
        return GameWorld.getWorld();
    }

    @Override
    public void sendKeyPress(KeyEvent ke) {
        System.out.println(ke.getKeyChar());
    }

    @Override
    public void sendMouseMove(MouseEvent me) {

    }

}

堆栈跟踪:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at com.pvminecraft.gameworld.Main.<clinit>(Main.java:14)
Caused by: java.lang.NullPointerException
at com.pvminecraft.gameworld.entities.EntityPlayer.<init>(EntityPlayer.java:45)
at com.pvminecraft.gameworld.GameWorld.<init>(GameWorld.java:15)
at com.pvminecraft.gameworld.GameWorld.<clinit>(GameWorld.java:13)
... 1 more

Main.java的第14行是我获取GameWorld的另一个实例进行测试。我不确定为什么会抛出异常。如果我删除EntityPlayer中对GameWorld的引用,它就会消失。如果你需要Main.java的代码,请在评论中告诉我,我会发布它。谢谢!

编辑:EntityPlayer中的第45行是“input = world.getInputController();”我很确定世界是空的,虽然我不知道为什么。

java singleton nullpointerexception
2个回答
2
投票

你正在转向自己。

您想要初始化GameWorld.INSTANCE变量。在此之前,您必须初始化GameWorld类的所有字段。初始化所有字段后,将分配变量INSTANCE。在此之前,它仍然具有默认值null

在初始化期间,字段player被初始化。在初始化中,您已经访问了INSTANCE字段。所以你有一个循环依赖。

你真的必须解开你的班级,这样他们就会变得更加独立。


0
投票

我没有看到表达的任何保证

InputController.getInput()

返回非null。由于您的代码非常适合调试(每行至少有一个NullPointerException),因此查看哪个变量为null应该是微不足道的。

正如我所说,我怀疑input

© www.soinside.com 2019 - 2024. All rights reserved.