Ingo Bürk Ingo Bürk - 20 days ago 8
Java Question

Does Arrays.copyOf produce a shallow or a deep copy?

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?

Answer

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.