Reputation: 597076
int[][] array = new int[][] {...}
int[][] clone = array.clone();
I naively expected this to work. But it didn't - it cloned only the first dimension, and I had to go and clone the other dimension manually if I wanted a true clone. Note: the contents were properly copied. But when I changed clone[0][1]
, it reflected in array[0][1]
And while .clone()
is known to perform a shallow clone, int[][]
looks like a single object (if we don't know its internal implementation, at least)
Why is that behaviour chosen? Isn't int[][]
referencing an array object, rather than just the first dimension of the array? And in what scenarios is cloning only the first dimension the desired behaviour?
Upvotes: 18
Views: 2911
Reputation: 5522
I am actually not able to replicate the behavior you have mentioned. I can see some answers mentioning shallow copy as the root cause of the issue. Correct me if I am wrong, shallow copy just means that instead of copy of an object while cloning, we will get copy of the reference. A good explanation can be found here In Java, what is a shallow copy?
In this case shallow copy will only make sure that changes in original array get reflected in the cloned array but will not stop anything from being copied.
int[][] array = new int[][] {{1,2,3},{4,5,6}, {7,8,9}};
int[][] clone = array.clone();
//Try this to see magic of shallow copy
//array[2][1]=11;
for(int i=0;i<array.length;i++)
for(int j=0;j<array[i].length;j++)
System.out.println("array["+i+"]["+j+"]"+array[i][j]);
for(int i=0;i<clone.length;i++)
for(int j=0;j<clone[i].length;j++)
System.out.println("clone["+i+"]["+j+"]"+clone[i][j]);
For me the cloning is done perfectly, that is both arrays have same contents. The only reason I can think of for getting the issue that cloned array will not show some information is that we have actually modified original array after the cloning (shallow copy comes into play then).
BTW I used Java 1.6, I hope that is not an issue.
Edit: If we just need to understand why their is a shallow copy instead of deep copy of a multidimensional array. Let's look at 2 facts
Now combining 1 and 2, we know that multidimensional array in Java is just an object, which has reference of other array objects.
Something like ArrayObj->{ArrayObj, ArrayObj, ArrayObj};
And because we have Objects inside objects (composition), we are supposed to get a shallow copy as per Java cloning rule.
Upvotes: 1
Reputation: 2710
The clone
method is a so called shallow copy (see another stackoverflow answer on the clone
method), which means that all the elements are copied by reference.
To get to what you want (also called deep cloning) you can either copy every single array yourself using the Arrays.copy
recursively, so every (sub-)array you find will get a deep-clone, or check this stackoverflow answer on deep cloning.
Happy hacking :-)
Upvotes: 1
Reputation: 677
This behavior is demonstrated because there is no true multi dimensional array.
Java achieves multiple dimensions by making arrays of arrays. Which means:
int[][] is actually Array<Array<int>>
Hence the clone would only copy the first dimension.
If you were trying with a 3 dimensional array, you would need to clone thrice.
Upvotes: 3
Reputation: 103787
Why is that behaviour chosen?
Consistency, most likely.
As you say, int[][]
references an array object. It just so happens that the contents of each array element is another array, but that's just a detail. Java clones all arrays identically, and since the elements can be of any type it can't guarantee to perform a deep copy.
Hence clone()
for arrays performs a shallow copy, so only the first dimension is cloned.
(In general it doesn't seem that there's a single "best" or "obvious" answer to the question of whether a clone implies deep or shallow copies. What the developer wants will depend on how each field is being used by the application, so a one-size-fits-all approach will naturally have limitations.)
Upvotes: 8