Метод клонирования для массивов Java

что именно возвращает метод clone() в Java при использовании в массиве? Это возвращает новый массив с данными, скопированными с оригинала?

Ex:

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

2 ответов


когда 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

это становится немного сложнее, когда исходный массив содержит объекты. The 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

если вы вообще понимаете, как работают ссылки на объекты, легко понять, как массивы объектов влияют на клонирование и варианта исполнения. Чтобы получить дальнейшее представление о ссылках и примитивах, я бы предложил прочитать это отличное статьи.

суть исходного кода


clone() метод создает и возвращает копию этого объекта. Точное значение слова "копировать" может зависеть от класса объекта. Общее намерение состоит в том, что для любого объекта X, выражение:

 x.clone() != x

будет верно, и что выражение:

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

будет верно, но это не абсолютные требования.

в то время как это обычно бывает, что:

 x.clone().equals(x)

будет верно, это не абсолют требование.

по соглашению возвращаемый объект должен быть получен путем вызова super.clone. Если класс и все его суперклассы (кроме Object) подчиняются этому соглашению, это будет так, что x.clone().getClass() == x.getClass().