Клонирует ли также вызов clone () в массиве его содержимое?
92
Если я вызову clone()метод для массива объектов типа A, как он будет клонировать свои элементы? Будет ли копия ссылаться на те же объекты? Или это потребует (element of type A).clone()каждого из них?
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("-----");
}
И, если бы вы собирались это сделать, лично я бы использовал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()ни одного из элементов.
Вы хотите сказать, что я могу получить 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].
Ответы:
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 -----
источник
System.arrayCopy
clone()
- хороший вариант для использования с массивами .. почти исключительно. Блох упоминает, что он будет использовать его только для массивов и ничего больше.System.arrayCopy
Это хорошо.Arrays.copyOf(..)
- еще одна альтернатива, более простая в использовании.Arrays.copyOf
:-) У него есть сигнатура метода, которая упрощает переменные (да, она ограничивает вас, но идеально подходит для большинства случаев), и, по крайней мере, в моем JDK она реализована вSystem.arrayCopy
любом случае. Спасибо за совет!array[i].clone()
НЕ относится кarray[i]
. Вот что демонстрирует эта часть примера.Элементы массива не будут клонированы.
Да.
Нет, это не вызовет
clone()
ни одного из элементов.источник
Одномерный массив примитивов копирует элементы при клонировании. Это соблазняет нас клонировать 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 }
источник
clone
одномерный массив примитивов и получить его полную копию? Это так здорово! Стоимость проезда хорошоArrays.copyOfRange()
,System.arraycopy()
!Клон - это неглубокая копия массива.
Этот тестовый код печатает:
поскольку используется
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)); } }
источник