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