引用变量到Java中另一个类中实例化/初始化的对象

时间:2011-01-11 20:44:11

标签: java reference initialization nullpointerexception

我问的原因是因为我收到了NullPointerException。 我现在这很容易,但我很新编程,发现这有点令人困惑。 所以说我已经在类中初始化了一个对象,并希望从另一个类访问该对象。

就像现在我正在制作一个小型国际象棋游戏,在我的模型游戏类中,我有一个Board实例,一个对象。反过来,董事会有一系列Squares。平方[] []。

游戏有棋盘,棋盘有Square [] []。

现在,如果我想通过Board类型的对象板(在游戏中)访问Square [] []。 我只是声明一个具有相同名称和类型的变量,还是我必须再次初始化它?

Board Board OR Board board = new Board();

注意,我已经在游戏类中初始化了棋盘,所以如果我再次这样做,它们不会是两个完全不同的棋盘对象吗?

引用“董事会”的类:

public class View extends JFrame {

Board      board;
JFrame     gameWindow   = new JFrame("Chess");
JPanel     gamePanel    = new JPanel();
JPanel[][] boardPanel   = new JPanel[8][8];
JMenuBar   gameMenu     = new JMenuBar();
JButton    newGame      = new JButton("New game");
JButton    pauseGame    = new JButton("Pause");
JButton    actionLog    = new JButton("Action log");

View(){
    gameWindow.setDefaultCloseOperation(EXIT_ON_CLOSE);
    gameWindow.setSize(400, 400);
    gameWindow.getContentPane().add(gamePanel);
    gameWindow.setVisible(true);
    gamePanel.setVisible(true);
    gameMenu.add(newGame);
    gameMenu.add(pauseGame);
    gameMenu.add(actionLog);
    for(JPanel[] row : boardPanel){
        for(JPanel box : row){
            gamePanel.add(box);
        }
    }
}

public void drawBoard(){
    for(int y = 0; y < 8; y++){
        for(int x = 0; x < 8; x++){
            Box box = new Box();
            box.setColour(board.getSquare(x, y).getColour());
            box.setCol(x);
            box.setRow(y);
            box.repaint();
            boardPanel[x][y].add(box);
        }
    }
}

}

class Box extends JComponent{
JPanel[][] boardPanel;
Board board;
Color boxColour;
int col, row;
public Box(){
    repaint();
}
public void paint(Graphics drawBox){
    drawBox.setColor(boxColour);
    drawBox.drawRect(50*col, 50*row, 50, 50);
    drawBox.fillRect(50*col, 50*row, 50, 50);
}
public void setColour(Color boxColour){
    this.boxColour = boxColour;
}

public void setCol(int col){
    this.col = col;
}

public void setRow(int row){
    this.row = row;
}

}

...以及实例化“board”的类:

public class Game {

@SuppressWarnings("unused")
public static void main(String[] args) 
        throws Throwable{
    Board board = new Board();
    View view = new View();
}

}

此处发生异常:

        for(JPanel[] row : boardPanel){
        for(JPanel box : row){
            gamePanel.add(box);
        }
    }

5 个答案:

答案 0 :(得分:3)

  

注意,我已经在游戏类中初始化了棋盘,所以如果我再次这样做,它们不会是两个完全不同的棋盘对象吗?

是的,那么你将有两个完全不同的实例。你得到了基本的想法 - 你的程序中有对象的实例,现在你必须让它们一起工作。

  

现在,如果我想通过Board类型的对象板(在游戏中)访问Square [] []。我只是声明一个具有相同名称和类型的变量,还是我必须再次初始化它?

你可以通过两种方式让游戏获得广场的访问权限(根据你的看法,可能只有2个以上):

1让董事会提供对Squares的访问权限(例如,在Board上返回Squares数组的getter方法),以便Game可以访问它们。然后,Board可以保存引用(有自己的实例变量来保存对方块的引用,或者每次都可以请求Board进行引用)。

2让董事会提供方法来完成游戏想要在广场上做的事情,即游戏要求董事会对广场做一些事情,并且董事会在广场上采取行动。

答案 1 :(得分:1)

NPE的原因是View类中的board字段实际上没有初始化。声明字段时,如果默认情况下未提供初始值设定项,则会将其初始化为null,因此语句Board board;会声明引用board的字段null

您可以通过声明Board board = new Board();来消除NPE,但这会创建一个新实例,这不是您想要的。相反,这里有两个选择:

  1. 为View类中的board字段添加一个getter和setter,并从main方法中调用它:

    public class View extends JFrame {
        Board      board;
        // ...
    
        public Board getBoard() { return board; }
        public void setBoard(Board b) { this.board = b; }
    }
    
    public class Game {
        @SuppressWarnings("unused")
        public static void main(String[] args) 
            throws Throwable{
        Board board = new Board();
        View view = new View();
        view.setBoard(board);
    }
    

    }

  2. 如果需要从构造函数中访问对象,则在构造函数中传递参数:

    public class View extends JFrame {
        Board      board;
        // ...
    
        View(Board b) {
            this.board = b;
            // ...
        }
    }
    
    public class Game {
        @SuppressWarnings("unused")
        public static void main(String[] args) 
            throws Throwable{
        Board board = new Board();
        View view = new View(board);
    }
    
  3. 第三种选择是使用Gursel Koca提到的单例模式,但我更愿意在可能的情况下避免使用它,因为如果你后来确定你确实需要多个类的一个实例,那么撤消可能会很痛苦。

答案 2 :(得分:0)

它们是两个不同的对象。如果你有新的NPE,你不应该得到NPE。可能是您的代码片段有助于检测NPE或NPE的堆栈跟踪也有帮助。

Board board1 = new Board(); //creates a new Board object 
Board board2 = new Board(); //creates another new Board object

答案 3 :(得分:0)

您在main()方法中创建的Board实例与View类的实例变量板不同。 View包含以下内容:

public class View extends JFrame { 
  Board      board;
  ...

永远不会为此变量板分配值(即新的Board())

然后,在Game类的main方法中,声明一个新的Board和一个新的View:

Board board = new Board();
View view = new View();

此变量板是main方法的局部变量,与View中的实例变量板无关。在View类中,您需要将变量声明更改为:

Board board = new Board();

答案 4 :(得分:-1)

NPE是由未实例化的对象引起的。所以解决它需要实例化。你可以使用new运算符来实现新的Board()