Java数组的克隆方法

时间:2013-01-04 01:08:58

标签: java arrays clone

当在数组上使用时,Java中的clone()方法究竟返回了什么? 它是否返回一个包含从原始数据复制的数据的新数组?

例如:

int[] a = {1,2,3};
int[] b = a.clone();

2 个答案:

答案 0 :(得分:80)

当在数组上调用clone方法时,它返回对新数组的引用,该数组包含(或引用)与源数组相同的元素。

因此,在您的示例中,int[] a是在堆上创建的单独对象实例,int[] b是在堆上创建的单独对象实例。 (记住所有数组都是对象)。

    int[] a = {1,2,3};
    int[] b = a.clone();

    System.out.println(a == b ? "Same Instance":"Different Instance");
    //Outputs different instance

如果要修改int[] b,则更改不会反映在int[] a上,因为这两个更改是单独的对象实例。

    b[0] = 5;
    System.out.println(a[0]);
    System.out.println(b[0]);
    //Outputs: 1
    //         5

当源数组包含对象时,这会变得稍微复杂一些。 clone方法将返回对新数组的引用,该数组引用与源数组相同的对象。

所以如果我们有班级Dog ......

    class Dog{

        private String name;

        public Dog(String name) {
            super();
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

    }

我创建并填充了Dog ...

类型的数组
    Dog[] myDogs = new Dog[4];

    myDogs[0] = new Dog("Wolf");
    myDogs[1] = new Dog("Pepper");
    myDogs[2] = new Dog("Bullet");
    myDogs[3] = new Dog("Sadie");

然后克隆狗......

    Dog[] myDogsClone = myDogs.clone();

数组引用相同的元素......

    System.out.println(myDogs[0] == myDogsClone[0] ? "Same":"Different");
    System.out.println(myDogs[1] == myDogsClone[1] ? "Same":"Different");
    System.out.println(myDogs[2] == myDogsClone[2] ? "Same":"Different");
    System.out.println(myDogs[3] == myDogsClone[3] ? "Same":"Different");
    //Outputs Same (4 Times)

这意味着如果我们修改通过克隆数组访问的对象,当我们访问源数组中的同一个对象时,将反映这些更改,因为它们指向相同的引用。

    myDogsClone[0].setName("Ruff"); 
    System.out.println(myDogs[0].getName());
    //Outputs Ruff

但是,对数组本身的更改只会影响该数组。

    myDogsClone[1] = new Dog("Spot");
    System.out.println(myDogsClone[1].getName());
    System.out.println(myDogs[1].getName());
    //Outputs Spot
    //        Pepper

如果您通常了解对象引用的工作原理,则很容易理解对象数组如何受到克隆和修改的影响。为了进一步了解参考文献和原语,我建议您阅读这篇优秀的article

Gist of Source Code

答案 1 :(得分:3)

clone()方法创建并返回此对象的副本。 “复制”的确切含义可能取决于对象的类别。一般意图是,对于任何对象x,表达式为:

 x.clone() != x

将是真的,那表达式:

 x.clone().getClass() == x.getClass()

确实如此,但这些并非绝对要求。

虽然通常情况如下:

 x.clone().equals(x)

将是真的,这不是绝对的要求。

按照惯例,应该通过调用super.clone来获取返回的对象。如果一个类及其所有超类(Object除外)遵守此约定,那么x.clone().getClass() == x.getClass()就是这种情况。