我试图在不使用任何库的情况下克隆对象。 该对象中包含其他对象/数组/矩阵。 所以我开发了一些方法来克隆它们。
当我克隆不在对象内的数组/矩阵时,它们正常工作。 这些是方法:
public static int[] cloneArray(int[] array){
int i = 0;
int[] clone = new int[array.length];
while (i < array.length){
clone[i] = array[i];
i++;
}
return clone;
}
public static int[][] cloneMatrix(int[][] matrix){
int[][] clone = new int[matrix.length][matrix[0].length];
for (int i = 0;i<matrix.length;i++)
for(int j = 0;j<matrix[0].length;j++)
clone[i][j] = matrix[i][j];
return clone;
}
但是,当我想要克隆一个对象时,数组/矩阵的引用保持不变,因为您可以检查帖子底部的输出。 这是我的构造函数:
public State(int parentStateID, int stateID, int[][] board, int[] pieces, int points, int acquiredPoints){
State.parentStateID = parentStateID;
State.stateID = stateID;
State.currentBoard = cloneMatrix(board); //here takes place the matrix cloning
State.currentPieces = cloneArray(pieces); //here takes place the array cloning
State.totalPoints = points;
State.acquiredPoints = acquiredPoints;
}
这是克隆方法:
public static State cloneState(State state){
int[][] currentBoard = state.getCurrentBoard();
int[] currentPieces = state.getCurrentPieces();
int totalPoints = state.getTotalPoints();
int acquiredPoints = state.getAcquiredPoints();
int parentStateID = state.getParentStateID();
int stateID = state.getStateID();
State clone = new State(parentStateID,
stateID,
currentBoard,
currentPieces,
totalPoints,
acquiredPoints);
return clone;
}
为了更好地可视化输出,这里是数组和矩阵:
public static int piecesList[] = {1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
public static int piecesList2[] = {2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
public static int piecesList3[] = {3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
private static int[][] map = {{0,1,2,3,4},{5,6,7,8,9},{10,11,12,13,14},{15,16,17,18,19},{20,21,22,23,24}};
以下是验证码:
int[][] state2 = cloneMatrix(map);
state2[0][0] = 1;
System.out.println("map.original " + map[0][0]);
System.out.println("map.clone " + state2[0][0]);
System.out.println("");
System.out.println("");
int[] pc = cloneArray(piecesList);
pc[24] = 1;
System.out.println("pieces.original " + piecesList[24]);
System.out.println("pieces.clone " + pc[24]);
System.out.println("");
System.out.println("");
State newState = setFirstState();
State clonedState = cloneState(newState);
clonedState.setCurrentPieces(piecesList2);
System.out.println("newState.pieceslist: "+newState.getCurrentPieces()[0]);
System.out.println("clonedState.pieceslist: "+clonedState.getCurrentPieces()[0]);
System.out.println("piecesList.original: "+piecesList[0]);
System.out.println("");
newState.setCurrentPieces(piecesList3);
System.out.println("newState.pieceslist: "+newState.getCurrentPieces()[0]);
System.out.println("clonedState.pieceslist: "+clonedState.getCurrentPieces()[0]);
System.out.println("piecesList.original: "+piecesList[0]);
这是输出:
map.original 0
map.clone 1
pieces.original -1
pieces.clone 1
//as you can check in the next two cases, the change takes effect in both the original state, and the cloned state
newState.pieceslist: 2
clonedState.pieceslist: 2
piecesList.array variable: 1
newState.pieceslist: 3
clonedState.pieceslist: 3
piecesList.array variable: 1
试图解决这个问题超过12个小时,没有太大的成功...... 我尝试过库以及序列化但没有成功...... 非常感谢帮助!
答案 0 :(得分:2)
代码的问题在于字段(未显示)显然是static
,可以从构造函数中告知:
public State(int parentStateID, int stateID, int[][] board, int[] pieces, int points, int acquiredPoints){
State.parentStateID = parentStateID;
State.stateID = stateID;
State.currentBoard = cloneMatrix(board); //here takes place the matrix cloning
State.currentPieces = cloneArray(pieces); //here takes place the array cloning
State.totalPoints = points;
State.acquiredPoints = acquiredPoints;
}
构造函数应该改为:
public State(int parentStateID, int stateID, int[][] board, int[] pieces, int points, int acquiredPoints){
this.parentStateID = parentStateID;
this.stateID = stateID;
this.currentBoard = cloneMatrix(board); //here takes place the matrix cloning
this.currentPieces = cloneArray(pieces); //here takes place the array cloning
this.totalPoints = points;
this.acquiredPoints = acquiredPoints;
}
静态字段每个类只存在一次。对于从该类(或任何子类)构造的每个对象,存在一个非静态的字段。因此,您实际上创建了空的对象,以及您认为将存储在实际存储在类中的对象中的任何内容,从而在所有对象之间共享相同的数据。
根据经验,您通常不希望班级中有任何static
非final
字段。例外适用,但它们很少见,并且主要局限于框架中的一些微小的引导。