midwestcode midwestcode - 2 months ago 14
Java Question

Java Clone Class With Primitive Types

I am trying to create a deep copy of an

Object
(called
State
) to do modifications to one of the instances within it, then follow up with code that modifies the old
State
based on the new
State
.

Here is
State
:

public class State implements Cloneable {

// 0: empty
// 1: white
// 2: black
private int[][] board;

private int player;

public State(int[][] board, int player) {
this.board = board;
this.player = player;
}

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

public int getPlayer() {
return player;
}

public void setBoard(int[][] board) {
this.board = board;
}

public void setPlayer(int player) {
this.player = player;
}

@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}

}


Then, here is how I try and access it:

State temp = (State) s.clone();
Action act = determineAction(temp);
doSomething(s, act);


s
is a
State
passed into the method. After
determineAction
is called, for some reason the
board
in
s
is being modified along with
temp
even though it is not passed... How come this is? Shouldn't the call to
.clone()
clone instances of all primitive types such that they can be uniquely modified?

That is what this post suggests: http://howtodoinjava.com/core-java/cloning/a-guide-to-object-cloning-in-java/

I'm struggling to see why this wouldn't be deep copied, and why my modifications to
temp
would also modify
s
.

Any tips would be greatly appreciated -- thanks!

Edit - For anyone curious, here's what fixed it:

@Override
protected Object clone() throws CloneNotSupportedException {

State cloned = (State) super.clone();

int[][] clonedBoard = new int[8][8];

for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
clonedBoard[i][j] = board[i][j];
}
}

cloned.setBoard(clonedBoard);

return cloned;
}

Answer

super.clone() does not do a deep-copy, and an int[][] is not a primitive type.

It works for the int player because that is a primitive type and a simple copy (as done by Object#clone) is enough.

You need to (deep-) copy your int[][] yourself.