Clone () vs constructeur de copie qui est recommandé dans Java

méthode clone vs constructeur de copie dans java. quelle est la solution correcte. où utiliser chaque cas?

Le clone est cassé, alors ne l’utilisez pas.

LA MÉTHODE CLONE de la classe Object est une méthode quelque peu magique qui fait ce qu’aucune méthode Java pure ne peut jamais faire: elle produit une copie identique de son object. Il a été présent dans la super-classe primordiale Object depuis les jours de la version bêta du compilateur Java *; et, comme toute magie ancienne, il faut l’incantation appropriée pour empêcher le sort de se retourner de manière inattendue

Préférer une méthode qui copie l’object

 Foo copyFoo (Foo foo){ Foo f = new Foo(); //for all properties in FOo f.set(foo.get()); return f; } 

En savoir plus http://adtmag.com/articles/2000/01/18/effective-javaeffective-cloning.aspx

Gardez à l’esprit que clone() ne fonctionne pas immédiatement. Vous devrez implémenter Cloneable et remplacer la méthode clone() en public .

Il y a quelques alternatives, qui sont préférables (puisque la méthode clone() a beaucoup de problèmes de conception, comme indiqué dans d’autres réponses), et que le constructeur de copie nécessiterait un travail manuel:

  • BeanUtils.cloneBean(original) crée un clone peu profond, comme celui créé par Object.clone() . (cette classe est de commons-beanutils )

  • SerializationUtils.clone(original) crée un clone profond. (c.-à-d. que tout le graphe de propriétés est cloné, pas seulement le premier niveau) (à partir de commons-lang ), mais toutes les classes doivent implémenter Serializable

  • Java Deep Cloning Library offre un clonage profond sans avoir à implémenter Serializable

clone () a été conçu avec plusieurs erreurs (voir cette question ), il est donc préférable de l’éviter.

From Effective Java 2nd Edition , Point 11: Remplacer judicieusement le clone

Compte tenu de tous les problèmes associés à Cloneable, il est prudent de dire que les autres interfaces ne devraient pas l’étendre, et que les classes conçues pour l’inheritance (élément 17) ne devraient pas l’implémenter. En raison de ses nombreuses lacunes, certains programmeurs experts choisissent simplement de ne jamais remplacer la méthode de clonage et de ne jamais l’invoquer, sauf peut-être pour copier des tableaux. Si vous concevez une classe pour l’inheritance, sachez que si vous choisissez de ne pas fournir une méthode de clone protégée bien comscope, il sera impossible pour les sous-classes d’implémenter Cloneable.

Ce livre décrit également les nombreux avantages des constructeurs de copies par rapport à Cloneable / clone.

  • Ils ne s’appuient pas sur un mécanisme de création d’objects extralinguistiques sujet aux risques
  • Ils n’exigent pas une adhésion inapplicable aux conventions peu documentées
  • Ils n’entrent pas en conflit avec l’utilisation correcte des champs finaux
  • Ils ne jettent pas d’exceptions vérifiées inutiles
  • Ils ne nécessitent pas de moulages.

Toutes les collections standard ont des constructeurs de copie. Utilise les.

 List original = // some list List copy = new ArrayList(original); 

N’oubliez pas que le constructeur de copie limite le type de classe à celui du constructeur de copie. Prenons l’exemple:

 // Need to clone person, which is type Person Person clone = new Person(person); 

Cela ne fonctionne pas si la person peut être une sous-classe de Person (ou si Person est une interface). Ceci est le but principal de clone, c’est qu’il peut cloner dynamicment le type approprié à l’exécution (en supposant que le clone est correctement implémenté).

 Person clone = (Person)person.clone(); 

ou

 Person clone = (Person)SomeCloneUtil.clone(person); // See Bozho's answer 

Maintenant, la person peut être n’importe quel type de Person supposant que le clone est correctement implémenté.

Voir aussi: Comment remplacer correctement la méthode de clonage? . Le clonage est cassé en Java, il est si difficile de le faire correctement, et même quand il le fait, il n’en offre pas vraiment grand chose , donc ça ne vaut pas vraiment la peine.

Grande sortingstesse: ni Clonable / clone, ni un constructeur ne sont d’excellentes solutions: JE NE VEUX PAS CONNAÎTRE LA CLASSE D’EXÉCUTION !!! (par exemple, j’ai une carte que je veux copier, en utilisant la même implémentation cachée de MumbleMap), je veux juste faire une copie si cela est supporté. Mais, hélas, Cloneable ne dispose pas de la méthode de clonage, donc il n’ya rien à écrire en toute sécurité sur lequel invoquer clone ().

Quelle que soit la meilleure bibliothèque “object de copie”, Oracle devrait en faire un composant standard de la prochaine version de Java (sauf si elle est déjà cachée quelque part).

Bien sûr, si une plus grande partie de la bibliothèque (par exemple, Collections) était immuable, cette tâche de “copie” disparaîtrait. Mais alors nous commencerions à concevoir des programmes Java avec des éléments tels que “invariants de classe” plutôt que le modèle “haricot” de verdammt (créez un object cassé et modifiez-le jusqu’à ce qu’il soit assez bon).