如果我在类型为A的对象数组上调用
clone()
方法,它会如何克隆其元素?复制品是否将引用相同的对象?还是对每个元素都调用(类型为A的元素).clone()
?clone()
方法创建的是浅拷贝,这意味着元素不会被克隆。(如果它们没有实现Cloneable
接口怎么办?)
如果要复制数组,您可以使用Arrays.copyOf(..)
而非clone()
方法(虽然对于数组来说,克隆也没问题,但对于其他类型则不行)
如果需要深度克隆,请参考此答案
下面是一个简单的示例,用于说明即使元素是Cloneable
类型,clone()
仍然是浅拷贝:
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("-----");
}
输出:
4384790
4384790
9634993
-----
1641745
1641745
11077203
-----
System.arrayCopy
。 - corsiKaclone()
是一个很好的选项,几乎只用于数组。Bloch提到他只会将其用于数组,而不会用于其他任何情况。System.arrayCopy
也可以。Arrays.copyOf(..)
是另一种更易于使用的替代方案。 - BozhoArrays.copyOf
:-) 它有一个方法签名,可以简化变量(是的,它会限制你,但对于大多数情况来说是完美的),并且至少在我的JDK中,它是使用 System.arrayCopy
实现的。感谢您的提示! - corsiKa当克隆一个原始类型的1D数组时,它会复制元素。这让我们想去克隆一个2D数组(数组的数组)。
请记住,由于clone()
的浅拷贝实现,2D数组的克隆不起作用。
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
}
clone
一个基本类型的一维数组并获得深拷贝吗?太棒了!那就再见了,Arrays.copyOfRange()
和System.arraycopy()
! - Janez KuharMutableInteger
在两个数组中作为 objects[0]
和 objects2[0]
共享,但你可以独立地改变 objects[1]
的引用和 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));
}
}