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

Java中另一个类中实例化/初始化的对象的引用变量,java,reference,initialization,nullpointerexception,Java,Reference,Initialization,Nullpointerexception,我问的原因是因为我得到了NullPointerException。 我现在觉得这很简单,但我是一个相当新的编程人员,觉得这有点混乱。 假设我在一个类中初始化了一个对象,并希望从另一个类访问同一个对象 比如现在,我正在做一个小的国际象棋游戏,在我的模型游戏类中,我有一个棋盘的实例,一个对象。棋盘上依次有一组正方形。正方形[][] 游戏有棋盘,棋盘有方块[] 现在,如果我想通过board类型游戏中的对象板访问正方形[][]。 我是仅仅声明一个具有相同名称和类型的变量,还是必须再次初始化它 线路板或线

我问的原因是因为我得到了NullPointerException。 我现在觉得这很简单,但我是一个相当新的编程人员,觉得这有点混乱。 假设我在一个类中初始化了一个对象,并希望从另一个类访问同一个对象

比如现在,我正在做一个小的国际象棋游戏,在我的模型游戏类中,我有一个棋盘的实例,一个对象。棋盘上依次有一组正方形。正方形[][]

游戏有棋盘,棋盘有方块[]

现在,如果我想通过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);
        }
    }
}
}

…以及实例化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);
        }
    }

NPE是由未实例化的对象引起的。因此,解决它需要实例化。您可以使用new操作符执行此操作,因此new Board

NPE的原因是视图类中的Board字段实际上没有初始化。当您声明一个字段时,如果您默认不提供初始值设定项,它将被初始化为null,因此语句板;声明引用null的字段板

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

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

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

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
注意,我已经在类游戏中初始化了棋盘,所以如果我再次初始化,它们不是两个完全不同的棋盘对象吗

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

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

你有2种方法可以让游戏进入方格,根据你的看法,可能不止2种:

1让棋盘提供对方块的访问,例如,棋盘上返回方块数组的getter方法,以便游戏可以访问它们。然后,Board可以保存引用并拥有自己的实例变量来保存对正方形的引用,或者每次都可以向Board请求引用


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

在主方法中创建的棋盘实例与视图类的实例变量棋盘不同。视图包含以下内容:

public class View extends JFrame { 
  Board      board;
  ...
此可变板从未分配值,即新板

然后,在游戏类的主方法中,声明一个新板和一个新视图:

Board board = new Board();
View view = new View();
此变量板是main方法的局部变量,与视图中的实例变量板没有关系。在视图类中,需要将变量声明更改为:

Board board = new Board();

哦,好吧,但这正是我困惑的地方。我已经在我的一个类中实例化了它,我想使用那个特定的对象。如果我再次实例化它,它不会创建一个不同的对象吗?我想说的是,我已经有了董事会=新董事会;在我的一个类中,比如说类A。如果我在类B中使用Board Board=new Board再次实例化它,然后使用参考板,它会引用与类A中相同的实例吗?这取决于定义Board变量的位置,该变量是scope,而不取决于scope。他们是完全不同的对象。。若你们想每次访问同一个线路板对象,你们可以使用单例模式..错误答案。NPE是由空引用引起的。创建一个新实例远远不是设置对null以外的对象的引用的唯一方法。@Navi:String a=hello;字符串b=a你是说b现在是空的吗?可以使用赋值运算符将引用赋值给任何对象,而不仅仅是内联创建的新实例。可以将代码放在这里吗?具有
定义的位置。哦,但游戏可以进入棋盘和方格。游戏有一个棋盘的实例。我的意思是,我正试图从gui中分离模型,我需要一个对board的引用,游戏中的同一个实例,在我的gui类中。我想补充一点,根据上面提供的信息,选择2似乎更合适。游戏不应该直接访问方块,它应该调用棋盘来间接操纵它们。@Alex-为了使这个答案更符合您的具体问题,您可能会选择选项1,这意味着游戏应该有一个返回棋盘参考的getBoard方法。好的,谢谢。如果你不介意我问,那有什么用?我是否应该在我的视图类中创建一个游戏实例来访问board,然后在我的游戏类中创建一个视图实例来提供GUI?@Alex-为了遵循MVC的原则,您的模型类board和Square不应该知道任何GUI/视图类,但是视图类可以知道模型类。至于创建实例,我将在主方法中创建一个游戏实例,然后在主方法中创建视图实例时将游戏传递给视图的构造函数。然后视图可以作为实例变量维护对游戏的引用。谢谢!回答得好。我将它作为参数传递给了实际需要它的方法。不过我还是从另一个渠道得到了NPE。似乎找不到问题所在,所以我可能会问另一个问题。
Board board = new Board();