¿Llamar a clone () en una matriz también clona su contenido?
92
Si invoco el clone()método en una matriz de objetos de tipo A, ¿cómo clonará sus elementos? ¿La copia hará referencia a los mismos objetos? ¿O llamará (element of type A).clone()a cada uno de ellos?
clone()crea una copia superficial. Lo que significa que los elementos no se clonarán. (¿Y si no lo implementaron Cloneable?)
Es posible que desee utilizar Arrays.copyOf(..)para copiar matrices en lugar de clone()(aunque la clonación está bien para matrices, a diferencia de cualquier otra cosa)
Un pequeño ejemplo para ilustrar la poca profundidad de clone()incluso si los elementos son Cloneable:
ArrayList[] array =newArrayList[]{newArrayList(),newArrayList()};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("-----");}
Y, si fueras a hacer eso, personalmente usaríaSystem.arrayCopy
corsiKa
1
clone()es una buena opción para usar con matrices ... casi exclusivamente. Bloch menciona que lo usaría solo para matrices y nada más. System.arrayCopyestá bien. Arrays.copyOf(..)es otra alternativa más fácil de utilizar.
Bozho
Lo Arrays.copyOfretiro, usaría :-) Tiene una firma de método que simplifica las variables (sí, te limita, pero es perfecto para la mayoría de los casos) y en mi JDK al menos, se implementa usando de System.arrayCopytodos modos. ¡Gracias por ese consejo!
corsiKa
@Bozho, de tu eg. array [i] y clone [i] se referirían al mismo objeto, por lo que los dos primeros sistemas son iguales. Pero matriz [i] .clone también se referiría a la matriz [i] en sí misma, entonces, ¿por qué matriz [i] .clone () devuelve un valor de código hash diferente?
abhihello123
@weakstudent, array[i].clone()NO hace referencia a array[i]. Eso es lo que está demostrando esa parte del ejemplo.
Dathan
19
Si invoco el método clone () en una matriz de objetos de tipo A, ¿cómo clonará sus elementos?
Los elementos de la matriz no se clonarán.
¿La copia hará referencia a los mismos objetos?
Si.
¿O llamará (elemento de tipo A) .clone () para cada uno de ellos?
¿Me está diciendo que puedo una clonematriz 1D de primitivas y obtener una copia en profundidad? ¡Eso es tan increíble! Vaya bien Arrays.copyOfRange(), System.arraycopy()!
Janez Kuhar
1
¡Yessssss! La matriz 1D de primitivas se copia cuando se clona la matriz
Thamme Gowda
1
Tenga en cuenta que Thamme Gowda N dice "primitivos". Los clones de matrices de objetos serán simplemente un clon de referencias.
Kristiaan
debido a que los primitivos no tienen estado, son inherentemente inmutables. No puede hacer una copia superficial de las primitivas, ya que no hay referencia
Xerus
5
El clon es una copia superficial de la matriz.
Este código de prueba imprime:
[1, 2] / [1, 2]
[100, 200] / [100, 2]
porque MutableIntegerse comparte en ambas matrices como objects[0]y objects2[0], pero puede cambiar la referencia objects[1]independientemente de objects2[1].
Respuestas:
clone()
crea una copia superficial. Lo que significa que los elementos no se clonarán. (¿Y si no lo implementaronCloneable
?)Es posible que desee utilizar
Arrays.copyOf(..)
para copiar matrices en lugar declone()
(aunque la clonación está bien para matrices, a diferencia de cualquier otra cosa)Si desea una clonación profunda, marque esta respuesta
Un pequeño ejemplo para ilustrar la poca profundidad de
clone()
incluso si los elementos sonCloneable
:Huellas dactilares:
fuente
System.arrayCopy
clone()
es una buena opción para usar con matrices ... casi exclusivamente. Bloch menciona que lo usaría solo para matrices y nada más.System.arrayCopy
está bien.Arrays.copyOf(..)
es otra alternativa más fácil de utilizar.Arrays.copyOf
retiro, usaría :-) Tiene una firma de método que simplifica las variables (sí, te limita, pero es perfecto para la mayoría de los casos) y en mi JDK al menos, se implementa usando deSystem.arrayCopy
todos modos. ¡Gracias por ese consejo!array[i].clone()
NO hace referencia aarray[i]
. Eso es lo que está demostrando esa parte del ejemplo.Los elementos de la matriz no se clonarán.
Si.
No, no llamará
clone()
a ninguno de los elementos.fuente
La matriz 1D de primitivas copia elementos cuando se clona. Esto nos tienta a clonar una matriz 2D (matriz de matrices).
Recuerde que la clonación de matriz 2D no funciona debido a la implementación de copia superficial de
clone()
.fuente
clone
matriz 1D de primitivas y obtener una copia en profundidad? ¡Eso es tan increíble! Vaya bienArrays.copyOfRange()
,System.arraycopy()
!El clon es una copia superficial de la matriz.
Este código de prueba imprime:
porque
MutableInteger
se comparte en ambas matrices comoobjects[0]
yobjects2[0]
, pero puede cambiar la referenciaobjects[1]
independientemente deobjects2[1]
.fuente