Подтвердить что ты не робот

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

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

Пример:

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

Ответ 1

Когда метод 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

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

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

Ответ 2

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

 x.clone() != x

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

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

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

Хотя обычно бывает, что:

 x.clone().equals(x)

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

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