Respostas:
clone()
cria uma cópia superficial. O que significa que os elementos não serão clonados. (E se eles não implementaram Cloneable
?)
Você pode querer usar Arrays.copyOf(..)
para copiar matrizes em vez de clone()
(embora a clonagem seja boa para matrizes, ao contrário de qualquer outra coisa)
Se você quiser clonagem profunda, verifique esta resposta
Um pequeno exemplo para ilustrar a superficialidade de clone()
até mesmo se os elementos forem 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("-----");
}
Impressões:
4384790
4384790
9634993
-----
1641745
1641745
11077203
-----
System.arrayCopy
clone()
é uma boa opção para usar com arrays ... quase exclusivamente. Bloch menciona que ele o usaria apenas para matrizes e nada mais. System.arrayCopy
está bem. Arrays.copyOf(..)
é outra alternativa mais fácil de usar.
Arrays.copyOf
:-) Ele tem uma assinatura de método que simplifica as variáveis (sim, limita você, mas é perfeito para a maioria dos casos) e no meu JDK, pelo menos, é implementado usando System.arrayCopy
assim mesmo. Obrigado por essa dica!
array[i].clone()
NÃO se refere a array[i]
. Isso é o que essa parte do exemplo está demonstrando.
Se eu invocar o método clone () na matriz de Objetos do tipo A, como ele clonará seus elementos?
Os elementos da matriz não serão clonados.
A cópia fará referência aos mesmos objetos?
Sim.
Ou irá chamar (elemento do tipo A) .clone () para cada um deles?
Não, não chamará clone()
nenhum dos elementos.
A matriz 1D de primitivas copia elementos quando é clonada. Isso nos tenta a clonar array 2D (Array of Arrays).
Lembre-se de que o clone de array 2D não funciona devido à implementação de cópia superficial de 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
1D array de primitivas e obter uma cópia profunda? Isso é tão incrível! Saem bem Arrays.copyOfRange()
, System.arraycopy()
!
O clone é uma cópia superficial da matriz.
Este código de teste imprime:
[1, 2] / [1, 2] [100, 200] / [100, 2]
porque o MutableInteger
é compartilhado em ambos os arrays como objects[0]
e objects2[0]
, mas você pode alterar a referência objects[1]
independentemente de 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));
}
}