L'appel de clone () sur un tableau clone-t-il également son contenu?
92
Si j'appelle la clone()méthode sur un tableau d'objets de type A, comment clonera-t-elle ses éléments? La copie fera-t-elle référence aux mêmes objets? Ou cela fera-t-il appel (element of type A).clone()à chacun d'eux?
clone()crée une copie superficielle. Ce qui signifie que les éléments ne seront pas clonés. (Et s'ils ne l'ont pas mis en œuvre Cloneable?)
Vous voudrez peut-être utiliser Arrays.copyOf(..)pour copier des tableaux au lieu de clone()(bien que le clonage soit bien pour les tableaux, contrairement à quoi que ce soit d'autre)
Un petit exemple pour illustrer la superficialité de clone()même si les éléments sont 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("-----");}
Et, si vous deviez faire cela, personnellement, j'utiliseraisSystem.arrayCopy
corsiKa
1
clone()est une bonne option à utiliser avec des tableaux .. presque exclusivement. Bloch mentionne qu'il ne l'utiliserait que pour les tableaux et rien d'autre. System.arrayCopyc'est bien. Arrays.copyOf(..)est une autre alternative plus simple à utiliser.
Bozho
Je le reprends - j'utiliserais Arrays.copyOf:-) Il a une signature de méthode qui simplifie les variables (oui ça vous limite, mais c'est parfait pour la plupart des cas) et dans mon JDK au moins, il est implémenté en utilisant de System.arrayCopytoute façon. Merci pour cette astuce!
corsiKa
@Bozho, de votre exemple. array [i] et clone [i] feraient référence au même objet, donc les deux premiers sysouts sont identiques. Mais array [i] .clone ferait également référence au tableau [i] lui-même alors pourquoi array [i] .clone () renvoie-t-il une valeur de hashcode différente?
abhihello123
@weakstudent, array[i].clone()ne fait PAS référence à array[i]. C'est ce que démontre cette partie de l'exemple.
Dathan
19
Si j'invoque la méthode clone () sur un tableau d'objets de type A, comment clonera-t-elle ses éléments?
Les éléments du tableau ne seront pas clonés.
La copie fera-t-elle référence aux mêmes objets?
Oui.
Ou appellera-t-il (élément de type A) .clone () pour chacun d'eux?
Non, il ne fera appel clone()à aucun des éléments.
Êtes-vous en train de me dire que je peux clone1D tableau de primitives et obtenir une copie complète? C'est tellement génial! Fare bien Arrays.copyOfRange(), System.arraycopy()!
Janez Kuhar
1
Yessssss! Le tableau 1D de primitives est copié lorsque le tableau est cloné
Thamme Gowda
1
Notez que Thamme Gowda N dit «primitifs». Les clones de tableaux d'objets ne seront qu'un clone de références.
Kristiaan
parce que les primitifs n'ont pas d'état, ils sont intrinsèquement immuables. Vous ne pouvez pas faire une copie superficielle des primitives, car il n'y a pas de référence
Xerus
5
Le clone est une copie superficielle du tableau.
Ce code de test imprime:
[1, 2] / [1, 2]
[100, 200] / [100, 2]
car le MutableIntegerest partagé dans les deux tableaux en tant que objects[0]et objects2[0], mais vous pouvez modifier la référence objects[1]indépendamment de objects2[1].
Réponses:
clone()
crée une copie superficielle. Ce qui signifie que les éléments ne seront pas clonés. (Et s'ils ne l'ont pas mis en œuvreCloneable
?)Vous voudrez peut-être utiliser
Arrays.copyOf(..)
pour copier des tableaux au lieu declone()
(bien que le clonage soit bien pour les tableaux, contrairement à quoi que ce soit d'autre)Si vous voulez un clonage profond, cochez cette réponse
Un petit exemple pour illustrer la superficialité de
clone()
même si les éléments sontCloneable
:Impressions:
la source
System.arrayCopy
clone()
est une bonne option à utiliser avec des tableaux .. presque exclusivement. Bloch mentionne qu'il ne l'utiliserait que pour les tableaux et rien d'autre.System.arrayCopy
c'est bien.Arrays.copyOf(..)
est une autre alternative plus simple à utiliser.Arrays.copyOf
:-) Il a une signature de méthode qui simplifie les variables (oui ça vous limite, mais c'est parfait pour la plupart des cas) et dans mon JDK au moins, il est implémenté en utilisant deSystem.arrayCopy
toute façon. Merci pour cette astuce!array[i].clone()
ne fait PAS référence àarray[i]
. C'est ce que démontre cette partie de l'exemple.Les éléments du tableau ne seront pas clonés.
Oui.
Non, il ne fera appel
clone()
à aucun des éléments.la source
Le tableau 1D de primitives copie les éléments lorsqu'il est cloné. Cela nous incite à cloner un tableau 2D (Array of Arrays).
N'oubliez pas que le clonage de tableau 2D ne fonctionne pas en raison de l'implémentation de copie superficielle de
clone()
.la source
clone
1D tableau de primitives et obtenir une copie complète? C'est tellement génial! Fare bienArrays.copyOfRange()
,System.arraycopy()
!Le clone est une copie superficielle du tableau.
Ce code de test imprime:
car le
MutableInteger
est partagé dans les deux tableaux en tant queobjects[0]
etobjects2[0]
, mais vous pouvez modifier la référenceobjects[1]
indépendamment deobjects2[1]
.la source