在Java中复制对象

在Java中复制对象,java,Java,我有以下Java代码: boolean[][] defaultBoard = {{false, false, false}, {false, false, false}, {false, false, false}}; Board board = new Board(defaultBoard); Board nextBoard = new Board(defaultBoard); ne

我有以下Java代码:

boolean[][] defaultBoard = {{false, false, false},
                            {false, false, false},
                            {false, false, false}};
Board board = new Board(defaultBoard);
Board nextBoard = new Board(defaultBoard);
nextBoard.getBoard()[1][5] = true;
board.printBoard();
印刷板:

public void printBoard() {
    for (boolean row[] : board) {
        for (boolean cell : row) {
            System.out.print( cell ? "#" : "." );
        }
        System.out.println();
    }
    System.out.println();
}
但它又回来了

...
.#.
...

这让我觉得
nextBoard
board
具有相同的内存地址。我的问题是:如何创建
nextBoard
的副本,以便在编辑
nextBoard
时,
board
也不被编辑?

数组是一个对象,因此您将传递对
board
构造函数的引用。由于您使用的是同一个数组,
board
nextBoard
都共享同一个对象。要避免这种情况,请使用
clone
方法。这样,您将有一个
defaultBoard
数组的副本,每个实例都有自己的board。它将如下所示:

Board board = new Board(cloneBoard(defaultBoard));
Board nextBoard = new Board(cloneBoard(defaultBoard));

private boolean[][] cloneBoard(boolean[][] boardToClone) {
    boolean[][] clone = new boolean[boardToClone.length][];
    for(int i = 0; i < boardToClone.length; i++) {
        clone[i] = boardToClone[i].clone();
    }
    return clone;
}
Board Board=新板(cloneBoard(defaultBoard));
Board nextBoard=新板(cloneBoard(defaultBoard));
专用布尔值[][]克隆板(布尔值[][]克隆板){
布尔值[][]克隆=新布尔值[boardToClone.length][];
对于(int i=0;i
数组是一个对象,因此您将向
构造函数传递一个引用。由于您使用的是同一个数组,
board
nextBoard
都共享同一个对象。要避免这种情况,请使用
clone
方法。这样,您将有一个
defaultBoard
数组的副本,每个实例都有自己的board。它将如下所示:

Board board = new Board(cloneBoard(defaultBoard));
Board nextBoard = new Board(cloneBoard(defaultBoard));

private boolean[][] cloneBoard(boolean[][] boardToClone) {
    boolean[][] clone = new boolean[boardToClone.length][];
    for(int i = 0; i < boardToClone.length; i++) {
        clone[i] = boardToClone[i].clone();
    }
    return clone;
}
Board Board=新板(cloneBoard(defaultBoard));
Board nextBoard=新板(cloneBoard(defaultBoard));
专用布尔值[][]克隆板(布尔值[][]克隆板){
布尔值[][]克隆=新布尔值[boardToClone.length][];
对于(int i=0;i
使用任何Java对象子类中存在的方法,即,据我所知的所有方法。

使用任何Java对象子类中存在的方法,即,据我所知的所有方法。

不是
board
nextBoard
是相同的。它是传递给构造函数的
defaultBoard
数组。您需要传递不同的数组。否则,您只需修改相同的数组


更好的是,为了确保
Board
的实例始终包含一个新数组,我建议在构造函数中对数组进行深度复制。

Board和
nextBoard
不是相同的。它是传递给构造函数的
defaultBoard
数组。您需要传递不同的数组。否则,您只需修改相同的数组


更好的是,为了确保
Board
的实例始终包含一个新数组,我建议在构造函数中对数组进行深度复制。

在这种情况下,我会让Board创建一个大小为

class Board {
    final boolean[] board;

    public Board(int width, height) {
        board = new[width][height];
    }

    public boolean[][] getBoard() { return board; }

    public void set(int x, int y, boolean value) { board[x][y] = value; }
}
现在,您的代码如下所示

Board board = new Board(3, 3);
Board nextBoard = new Board(3, 3);
nextBoard.set(1, 2, true); // the last element is 2 not 5
board.printBoard();

在这种情况下,我会让电路板创建一个大小为

class Board {
    final boolean[] board;

    public Board(int width, height) {
        board = new[width][height];
    }

    public boolean[][] getBoard() { return board; }

    public void set(int x, int y, boolean value) { board[x][y] = value; }
}
现在,您的代码如下所示

Board board = new Board(3, 3);
Board nextBoard = new Board(3, 3);
nextBoard.set(1, 2, true); // the last element is 2 not 5
board.printBoard();

每次需要将新数组传递给对象时,您都需要创建一个新的新数组,以便对象可以看到一个新数组而不是同一个数组。

每次需要将新数组传递给对象时,您都需要创建一个新的新数组,以便对象可以看到一个新数组而不是同一个数组。

使用
short
和按位操作。
defaultBoard.clone()
。(但是你也需要克隆每一行。)如果你有一个3 x 3的电路板,你如何更新第六个元素,即
[5]
访问第六个元素。你可以通过
短的
和按位操作来实现同样的效果。
defaultBoard.clone()
。(但是你也需要克隆每一行。)如果你有一个3 x 3的板,你如何更新第六个元素,即
[5]
访问第六个元素。克隆不执行深度复制。。。这意味着行引用的是同一数组,这无法解决问题克隆不执行深度复制。。。这意味着行引用的是同一数组,这无法解决问题克隆不执行深度复制。。。这意味着行引用的是同一个数组,这并不能解决问题方法
cloneBoard
遍历每一行,生成一个克隆,因此应该可以正常工作。克隆不执行深度复制。。。这意味着行引用的是同一个数组,这并不能解决问题方法
cloneBoard
会遍历每一行并生成一个克隆,因此它应该可以正常工作。如果
Board
的构造函数生成了其输入的防御性副本,如果
Board
的构造函数对其输入进行了防御性复制,那么编写行为不端的客户端就更难了。