There seems to be a lot of confusion and different opinions on this out there ([1] and other sources) on whether Arrays.copyOf
will produce a deep or shallow copy.
This test suggests that the copy is deep:
String[] sourceArray = new String[] { "Foo" };
String[] targetArray = java.util.Arrays.copyOf( sourceArray, 1 );
sourceArray[0] = "Bar";
assertThat( targetArray[0] ).isEqualTo( "Foo" ); // passes
This test suggests that the copy is shallow:
String[][] sourceArray = new String[][] { new String[] { "Foo" } };
String[][] targetArray = java.util.Arrays.copyOf( sourceArray, 1 );
sourceArray[0][0] = "Bar";
assertThat( targetArray[0][0] ).isEqualTo( "Foo" ); // fails
Is the solution simply that a deep copy of the top-level dimension is made, but other dimensions are a shallow copy? What is the truth?
[1] How do I do a deep copy of a 2d array in Java?
A deep copy of an object is a copy whose properties do not share the same references (point to the same underlying values) as those of the source object from which the copy was made.
When you do a shallow copy you now have two new array objects, but each corresponding entry between the two arrays points to the same object (because the objects themselves haven't been copied; just the references have). Original Array: [0:]----> [object 0] [1:]----> [object 1] [2:]----> [object 2] [3:]----> [object 3]
A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original. A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.
It produces a shallow copy, i.e. a new array that contains "old" references (to the same objects, those are not being copied).
In particular, if you have nested arrays, those will not be copied. You will just get a new array whose "top level" points to the same "second level" arrays as the original did. Any changes inside those nested arrays will be reflected in both copy and original.
This test suggests that the copy is deep:
No, it does not. When you assign a new object to the "original" array, this does not affect the copy. It is, after all, a copy.
This is the same situation as:
String x = "foo";
String y = x;
x = "bar";
assertEquals(y, "foo");
No "deep copy" here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With