Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

java

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?

like image 270
Ingo Bürk Avatar asked Aug 21 '13 07:08

Ingo Bürk


People also ask

What is a deep copy of an array?

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.

What is a shallow copy of an array in Java?

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]

What is shallow and deep copy?

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.


1 Answers

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.

like image 139
Thilo Avatar answered Sep 20 '22 06:09

Thilo