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


92

如果我clone()在类型A的对象数组上调用方法,它将如何克隆其元素?副本将引用相同的对象吗?还是会要求(element of type A).clone()他们每个人?


3
您必须在每个元素上调用clone。
彼得·劳瑞2011年

Answers:


77

clone()创建一个浅表副本。这意味着将不会克隆元素。(如果他们没有执行该怎么办Cloneable怎么办?)

您可能要使用Arrays.copyOf(..)复制而不是复制数组clone()(尽管克隆复制对数组没问题,与其他任何东西都不一样)

如果要深度克隆,请检查此答案


一个小例子来说明clone()即使这些元素是浅薄的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("-----");
}

印刷品:

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

2
而且,如果您要这样做,我个人会使用System.arrayCopy
corsiKa 2011年

1
clone()是几乎与数组一起使用的好选择。布洛赫(Bloch)提到他只会将其用于数组,而不会使用其他任何东西。System.arrayCopy很好 Arrays.copyOf(..)是另一个更易于使用的选择。
2011年

我将其收回-我将使用Arrays.copyOf:-)它具有简化变量的方法签名(是的,它限制了您,但对于大多数情况而言是完美的),至少在我的JDK中,System.arrayCopy无论如何都使用了它。感谢您的提示!
corsiKa 2011年

@Bozho,来自您的 array [i]和clone [i]将引用相同的对象,因此前两个sysout是相同的。但是array [i] .clone也将引用array [i]本身,那么为什么array [i] .clone()返回不同的哈希码值?
abhihello123

@weakstudent,array[i].clone()不涉及array[i]。这就是示例中所展示的内容。
Dathan

19

如果我在类型A的对象数组上调用clone()方法,它将如何克隆其元素?

数组的元素将不会被克隆。

副本将引用相同的对象吗?

是。

还是会为它们每个调用(A类型的元素).clone()?

不,它不会调用clone()任何元素。


6

一维基元数组在克隆时会复制元素。这诱使我们克隆二维数组(Array of Arrays)。

请记住,由于的浅拷贝实现,二维数组克隆不起作用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
}

1
您是在告诉我我可以clone一维数组的原语并获得深层副本吗?太棒了!别了Arrays.copyOfRange()System.arraycopy()
Janez Kuhar '16

1
是的!克隆数组时将复制一维原始数组
Thamme Gowda

1
请注意,Thamme Gowda N说的是“原始语”。对象数组的克隆将只是引用的克隆。
克里斯蒂安

因为基元没有状态,所以它们本质上是不可变的。您无法对基元进行浅表复制,因为没有参考资料
Xerus

5

克隆是阵列的浅表副本。

该测试代码打印:

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

因为MutableInteger在两个阵列共享为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));                                                               
    }                                                                                                                                                    
}                                                                                                                                                        
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.