在数组上调用 clone()是否也会克隆其内容?

如果我对 A 类对象的数组调用 clone()方法,它将如何克隆它的元素?副本是否引用相同的对象?或者它会为它们调用 (element of type A).clone()吗?

103265 次浏览

clone() creates a shallow copy. Which means the elements will not be cloned. (What if they didn't implement Cloneable?)

You may want to use Arrays.copyOf(..) for copying arrays instead of clone() (though cloning is fine for arrays, unlike for anything else)

If you want deep cloning, check this answer


A little example to illustrate the shallowness of clone() even if the elements are Cloneable:

ArrayList[] array = new ArrayList[] {new ArrayList(), new ArrayList()};
ArrayList[] clone = array.clone();
for (int i = 0; i < clone.length; i ++) {
System.out.println(System.identityHashCode(array[i]));
System.out.println(System.identityHashCode(clone[i]));
System.out.println(System.identityHashCode(array[i].clone()));
System.out.println("-----");
}

Prints:

4384790
4384790
9634993
-----
1641745
1641745
11077203
-----

The clone is a shallow copy of the array.

This test code prints:

[1, 2] / [1, 2]
[100, 200] / [100, 2]

because the MutableInteger is shared in both arrays as objects[0] and objects2[0], but you can change the reference objects[1] independently from objects2[1].

import java.util.Arrays;


public class CloneTest {
static class MutableInteger {
int value;
MutableInteger(int value) {
this.value = value;
}
@Override
public String toString() {
return Integer.toString(value);
}
}
public static void main(String[] args) {
MutableInteger[] objects = new MutableInteger[] {
new MutableInteger(1), new MutableInteger(2) };
MutableInteger[] objects2 = objects.clone();
System.out.println(Arrays.toString(objects) + " / " +
Arrays.toString(objects2));
objects[0].value = 100;
objects[1] = new MutableInteger(200);
System.out.println(Arrays.toString(objects) + " / " +
Arrays.toString(objects2));
}
}

If I invoke clone() method on array of Objects of type A, how will it clone its elements?

The elements of the array will not be cloned.

Will the copy be referencing to the same objects?

Yes.

Or will it call (element of type A).clone() for each of them?

No, it will not call clone() on any of the elements.

1D array of primitives does copy elements when it is cloned. This tempts us to clone 2D array(Array of Arrays).

Remember that 2D array clone doesn't work due to shallow copy implementation of clone().

public static void main(String[] args) {
int row1[] = {0,1,2,3};
int row2[] =  row1.clone();
row2[0] = 10;
System.out.println(row1[0] == row2[0]); // prints false


int table1[][]=\{\{0,1,2,3},{11,12,13,14}};
int table2[][] = table1.clone();
table2[0][0] = 100;
System.out.println(table1[0][0] == table2[0][0]); //prints true
}