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

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

比如现在我正在做一个小型国际象棋游戏,在我的模型游戏类中,我有一个Board实例,一个对象。 反过来,董事会有一系列Squares。 广场[][]。

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

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

董事会或董事会董事会=新董事会();

注意,我已经在类Game中初始化了板,所以如果我再次执行它,它们不会是两个完全不同的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); } } 

注意,我已经在类Game中初始化了板,所以如果我再次执行它,它们不会是两个完全不同的Board对象吗?

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

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

您可以通过两种方式为游戏提供游戏访问权限(可能不仅仅是2,具体取决于您如何看待它):

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

2让棋盘提供方法来完成游戏想要在方块上做的事情,即游戏要求棋盘对方块做一些事情,棋盘在方块上做动作。

NPE的原因是View类中的board字段实际上没有初始化。 当你声明一个字段时,如果你没有默认提供一个初始化器,它会被初始化为null ,所以语句Board board; 声明一个引用null的字段board

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

  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); } 

第三种选择是使用Gursel Koca提到的单例模式,但我更愿意在可能的情况下避免使用它,因为如果您以后确定实际上需要多个类的实例,则撤消可能会很麻烦。

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

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

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

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

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

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

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

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

 Board board = new Board(); 

NPE是由未实例化的对象引起的。 所以解决它需要实例化。 你用新的运营商这样做,所以新的董事会()