java Null Pointer异常传递对象

时间:2014-04-21 21:21:11

标签: java swing nullpointerexception

我有一些创建Ship的类(Ship扩展GameObject类)并尝试将其添加到gameBoard。 为此,它告诉gameFrame按如下方式添加对象:

public void startNewGame() {
    Ship myShip = new Ship(GAME_BOARD_WIDTH / 2, GAME_BOARD_HEIGHT-1, SHIP_WIDTH,
            SHIP_HEIGHT);
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            gameFrame = new InvadersGameFrame();
        }
    });
    gameFrame.addGameObject(myShip); //Problem line
    gameFrame.repaint();
}

gameFrame然后调用:

GameBoard gameBoard = new GameBoard();
...
...
public void addGameObject(GameObject ob) {
    gameBoard.addGameObject(ob);
}

反过来又打电话:

public class GameBoard extends JPanel implements GameData{
    private JPanel gameBoard;
    private List<GameObject> objects = new ArrayList<>();

    public GameBoard() {
        gameBoard = new JPanel();
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        setBackground(Color.black);
        g.setColor(Color.RED);
        for(GameObject ob : objects){
            g.drawOval(ob.x, ob.y, ob.width, ob.height);
        }
    }

    //Places object into list for drawing upon next repaint.
    public void addGameObject(GameObject ob) {
        objects.add(ob);
    }
}

现在我的问题是,当我gameFrame.addGameObject(myShip);时,我收到一个空指针异常 棘手的是当我通过调试器运行时根本没有收到NPE(但我的对象列表似乎仍然是空的)。
另外,我可以跟进每一个并仍然看到myShip,所以我只是引用我的GameObject(Ship)错了吗? 我的addGameObject参数应该更抽象吗?

4 个答案:

答案 0 :(得分:4)

问题是你在gameFrame内部分配了Runnable,直到稍后才会运行。因此,在您调用gameFrame

时,gameFrame.addGameObject(myShip)可能为null

答案 1 :(得分:2)

问题可能是你使用的invokeLater,只要Swing感觉像是这样,可能会在 gameFrame.addGameObject(myShip)之后发生;

这在调试器中不会发生,因为它在某种程度上是竞争条件,在调试器中Swing在gameFrame.addGameObject(myShip)之前调用runmethod,因为你无法快速点击以预先发出该语句;)

答案 2 :(得分:1)

此问题的最佳解决方案是在run方法中移动这些语句,如下所示:

public void startNewGame() {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            Ship myShip = new Ship(GAME_BOARD_WIDTH / 2, GAME_BOARD_HEIGHT-1, 
                SHIP_WIDTH, SHIP_HEIGHT);
            gameFrame = new InvadersGameFrame();
            gameFrame.addGameObject(myShip); //Problem line
            gameFrame.repaint();
        }
    });
}

这样做,4个语句将按预期的顺序运行,并且在需要时该属性不会是null

答案 3 :(得分:0)

检查初始化该变量的范围。即新InvadersGameFrame()周围的花括号{}。 确保在创建对象后使用该对象