web-dev-qa-db-fra.com

Clone () vs Copy constructor - recommandé dans java

méthode de clonage vs constructeur de copie en Java. lequel est la solution correcte. Où utiliser chaque cas?

134
Jothi

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

THE CLONE METHOD de la classe Object est une méthode quelque peu magique qui fait ce qu'aucune méthode pure Java _ ne pourrait jamais faire: elle produit une copie identique de son objet. Il est présent dans la super classe primordiale Object depuis les jours de la version bêta du compilateur Java *; et, comme toute magie ancienne, nécessite l'incantation appropriée pour empêcher le sort de se retourner de façon inattendue.

Préfère une méthode qui copie l'objet

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

107
Tom

N'oubliez pas que clone() ne fonctionne pas immédiatement. Vous devrez implémenter Cloneable et écraser la méthode clone() dans public.

Quelques alternatives sont préférables (car la méthode clone() soulève de nombreux problèmes de conception, comme indiqué dans d'autres réponses), et le constructeur de copie nécessiterait un travail manuel:

53
Bozho

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

De Effective Java 2nd Edition , élément 11: Remplacer le clone judicieusement

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

Ce livre décrit également les nombreux avantages des constructeurs de copie sur Cloneable/clone.

  • Ils ne s'appuient pas sur un mécanisme de création d'objets extralinguistique sujet aux risques
  • Ils n'exigent pas une adhésion inapplicable à des conventions finement 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 d'incantation.

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

List<Double> original = // some list
List<Double> copy = new ArrayList<Double>(original);
32
Rose Perrone

N'oubliez pas que le constructeur de copie limite le type de classe à celui du constructeur de copie. Considérons l'exemple:

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

Cela ne fonctionne pas si person pourrait être une sous-classe de Person (ou si Person est une interface). C’est l’intérêt du clone, c’est qu’il peut peut cloner le bon type de manière dynamique au moment de 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, person peut être n'importe quel type de Person en supposant que clone est correctement implémenté.

18
Steve Kuo

Voir aussi: Comment remplacer correctement la méthode de clonage? . Le clonage est interrompu en Java, il est si difficile de bien faire les choses, et même s'il le fait ne fonctionne pas offre vraiment beaucoup , donc ça ne vaut pas vraiment la peine.

3
polygenelubricants

Grande tristesse: 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 en faire une copie, si cela est pris en charge. Mais, hélas, Cloneable n’a pas la méthode de clonage dessus, il n’existe donc aucun élément vers lequel vous pouvez taper en toute sécurité sur lequel appeler clone ().

Quelle que soit la meilleure bibliothèque de "copie d'objet" existante, Oracle devrait en faire un composant standard de la prochaine version Java (à moins qu'elle ne le soit déjà, cachée quelque part).

Bien sûr, si davantage de bibliothèques (par exemple - Collections) étaient immuables, cette tâche de "copie" disparaîtrait. Mais ensuite, nous commencerions à concevoir Java des programmes avec des éléments tels que des "invariants de classe" plutôt que le modèle "bean" de verdammt (créer un objet cassé et le muter jusqu'à ce qu'il soit correct [assez]).

2
Roboprog