Java: solution recommandée pour la profondeur de clonage et de la copie d'une instance
Je me demandais si il est recommandé de faire une profonde clone/copie de l'instance de java.
J'ai 3 solutions à l'esprit, mais je peux l'avoir à manquer, et j'aimerais avoir votre avis
edit: inclure Bohzo propositon et d'affiner la question: c'est plus profond que le clonage peu profonde clonage.
Le faire vous-même:
code le clone en main propriétés propriétés et vérifiez que mutable instances sont clonés trop.
pro:
- le contrôle de ce que sera effectué
- la rapidité d'exécution
contre:
- fastidieux à écrire et à maintenir
- correction d'un bug ventral (copier/coller de l'échec, manque de propriété, réaffectés mutable propriété)
Utiliser la réflexion:
Avec vos propres outils de réflexion ou externe avec une aide (comme jakarta commun-les haricots), il est facile d'écrire une copie générique de la méthode qui va faire le travail en une seule ligne.
pro:
- facile à écrire
- sans entretien
contre:
- moins de contrôle sur ce qui se passe
- correction d'un bug sujets avec mutable objet si l'instrument de réflexion à ne pas clone sous les objets trop
- ralentissement de l'exécution
Utiliser clone cadre:
Utiliser un framework qui le font pour vous, comme :
commons-lang SerializationUtils
Java Profonde Clonage De La Bibliothèque
Dozer
Kryo
pro:
- de même que la réflexion
- plus de contrôle sur ce que sera exactement être cloné.
contre:
- chaque mutable instance est complètement cloné, même à la fin de la hiérarchie
- peut être très lente à exécuter
Utilisation instrumentation du bytecode pour écrire clone au moment de l'exécution
javassit, BCEL ou cglib peut être utiliser pour générer un dédié cloner aussi rapide qu'une main écrits. Quelqu'un connait une lib à l'aide de l'un de ces outils pour cela ?
Ce que j'ai raté ici ?
Qu'on vous recommande ?
Grâce.
- apparemment Java Profonde Clonage de la Bibliothèque a déménagé ici : code.google.com/p/cloning
Vous devez vous connecter pour publier un commentaire.
Profond de clonage (clones de l'ensemble de la hiérarchie de l'objet):
commons-lang SerializationUtils - utilisation de la sérialisation - si toutes les classes sont sous votre contrôle et vous pouvez forcer la mise en œuvre de
Serializable
.Java Profonde Clonage De La Bibliothèque - l'utilisation de la réflexion - dans les cas où les classes ou les objets que vous voulez cloner sont hors de votre contrôle (une 3ème partie de la bibliothèque) et vous ne pouvez pas les faire mettre en œuvre
Serializable
, ou dans le cas où vous ne voulez pas mettre en œuvreSerializable
.Pour peu profonde clonage (clones seulement le premier niveau de propriétés):
communes-beanutils BeanUtils - dans la plupart des cas.
Printemps BeanUtils - si vous utilisez déjà le printemps, et donc avoir cet utilitaire sur le chemin de la classe.
J'ai volontairement omis le "do-it-yourself" option - API ci-dessus fournissent un bon contrôle sur quoi et quoi ne pas clone (par exemple à l'aide de
transient
, ouString[] ignoreProperties
), afin de réinventer la roue n'est pas préféré.ClassNotFound
exceptionJoshua Bloch livre un chapitre entier intitulé "Article 10: Remplacer Clone Judicieusement" dans lequel il va les raisons impérieuses clone pour la plupart, est une mauvaise idée, car le Java de spécifications pour les il crée beaucoup de problèmes.
Il fournit un peu d'alternatives:
Utiliser un modèle de fabrique en place d'un constructeur:
Utiliser un constructeur de copie:
Toutes les classes de collection dans le support de Java le constructeur de copie (par exemple, new ArrayList(l);)
Copyable
interface qui contient ungetCopy()
méthode. Utilisez simplement le prototype de modèle manuellement.newInstance()
méthode et laYum
constructeur ne copie ou copie?Depuis la version 2.07 Kryo prend en charge superficiel/profond de clonage:
Kryo est rapide, à la et de leur page, vous pouvez trouver une liste des sociétés qui l'utilisent dans la production.
Utilisation XStream toXML/fromXML dans la mémoire. Extrêmement rapide et a été autour pendant un long moment et va fort. Les objets n'ont pas besoin d'être Sérialisable et vous n'avez pas utiliser la réflexion (bien que XStream n'). XStream peut discerner les variables qui pointent vers le même objet, et non accidentellement faire deux copies de l'instance. Beaucoup de ce genre de détails qui ont été forgés au cours des années. Je l'ai utilisé pour un certain nombre d'années et c'est un aller. Il est aussi facile à utiliser que vous pouvez imaginer.
ou
À cloner,
De façon plus succincte:
Dépend.
Pour la vitesse, l'utilisation de BRICOLAGE.
Pour l'épreuve des balles, utiliser la réflexion.
BTW, la sérialisation n'est pas la même que la réflexion, que certains objets peuvent fournir substituée méthodes de sérialisation (readObject/writeObject) et ils peuvent être buggy
Je recommanderais le BRICOLAGE qui, combinée avec une bonne hashCode() et equals() la méthode devrait être facile de preuve dans un test unitaire.
Je te suggère de remplacer l'Objet.clone(), l'appel à super.clone() en premier et que d'appeler ref = ref.clone() sur toutes les références que vous voulez avoir de profondes copié. C'est plus ou moins le Faire vous-même approche, mais a besoin d'un peu moins de codage.
Pour des objets compliqués et lorsque la performance n'est pas significative-je utiliser gson
pour sérialiser l'objet json texte, puis désérialiser le texte pour obtenir un nouvel objet.
gson qui est basée sur la réflexion fonctionne dans la plupart des cas, sauf que
transient
champs ne seront pas copiés et les objets de référence circulaire à causeStackOverflowError
.