Клонирует ли также вызов clone () в массиве его содержимое?

92

Если я вызову clone()метод для массива объектов типа A, как он будет клонировать свои элементы? Будет ли копия ссылаться на те же объекты? Или это потребует (element of type A).clone()каждого из них?

Шимон
источник
3
Вы должны вызывать clone для каждого элемента.
Питер Лоури

Ответы:

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
1
clone()- хороший вариант для использования с массивами .. почти исключительно. Блох упоминает, что он будет использовать его только для массивов и ничего больше. System.arrayCopyЭто хорошо. Arrays.copyOf(..)- еще одна альтернатива, более простая в использовании.
Божо
Я беру его обратно - я бы использовал Arrays.copyOf:-) У него есть сигнатура метода, которая упрощает переменные (да, она ограничивает вас, но идеально подходит для большинства случаев), и, по крайней мере, в моем JDK она реализована в System.arrayCopyлюбом случае. Спасибо за совет!
corsiKa
@Bozho, из твоего, например. array [i] и clone [i] будут ссылаться на один и тот же объект, поэтому первые два системных вывода совпадают. Но array [i] .clone также будет относиться к самому array [i], так почему же array [i] .clone () возвращает другое значение хэш-кода?
abhihello123 02
@weakstudent, array[i].clone()НЕ относится к array[i]. Вот что демонстрирует эта часть примера.
Dathan
19

Если я вызываю метод clone () для массива объектов типа A, как он будет клонировать свои элементы?

Элементы массива не будут клонированы.

Будет ли копия ссылаться на те же объекты?

Да.

Или он вызовет (элемент типа A) .clone () для каждого из них?

Нет, это не вызовет clone()ни одного из элементов.

Bludzee
источник
6

Одномерный массив примитивов копирует элементы при клонировании. Это соблазняет нас клонировать 2D-массив (Array of Arrays).

Помните, что клонирование 2D-массива не работает из-за реализации неглубокого копирования 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
}
Thamme Gowda
источник
1
Вы хотите сказать, что я могу получить cloneодномерный массив примитивов и получить его полную копию? Это так здорово! Стоимость проезда хорошо Arrays.copyOfRange(), System.arraycopy()!
Janez Kuhar
1
Дассссс! Одномерный массив примитивов копируется при клонировании массива
Тамме Гауда, 01
1
Обратите внимание, что Thamme Gowda N говорит «примитивы». Клоны массивов объектов будут просто клоном ссылок.
Кристиан
поскольку примитивы не имеют состояния, они неизменны по своей природе. Невозможно сделать мелкую копию примитивов, поскольку нет ссылки
Ксер
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));                                                               
    }                                                                                                                                                    
}                                                                                                                                                        
Саймон Никерсон
источник