Considérez le code ci-dessous:
DummyBean dum = new DummyBean();
dum.setDummy("foo");
System.out.println(dum.getDummy()); // prints 'foo'
DummyBean dumtwo = dum;
System.out.println(dumtwo.getDummy()); // prints 'foo'
dum.setDummy("bar");
System.out.println(dumtwo.getDummy()); // prints 'bar' but it should print 'foo'
Donc, je veux copier le dum
à dumtwo
et le changement dum
sans affecter la dumtwo
. Mais le code ci-dessus ne fait pas cela. Quand je change quelque chose dum
, le même changement se produit dumtwo
également.
Je suppose que quand je dis dumtwo = dum
, Java copie uniquement la référence . Alors, existe-t-il un moyen de créer une nouvelle copie de dum
et de l'affecter à dumtwo
?
Basique: copie d'objets en Java.
Supposons un objet-
obj1
, qui contient deux objets, ContenuObj1 et ContenuObj2 .copie superficielle: la copie
superficielle crée une nouvelle
instance
classe de la même classe et copie tous les champs dans la nouvelle instance et la renvoie. La classe d'objets fournit uneclone
méthode et prend en charge la copie superficielle.Copie profonde:
une copie profonde se produit lorsqu'un objet est copié avec les objets auxquels il se réfère . L'image ci-dessous montre
obj1
qu'une copie complète a été effectuée dessus. Non seulement aobj1
été copié , mais les objets qu'il contient ont également été copiés. Nous pouvons utiliserJava Object Serialization
pour faire une copie complète. Malheureusement, cette approche pose également certains problèmes ( exemples détaillés ).Problèmes possibles:
clone
est difficile à mettre en œuvre correctement.Il est préférable d'utiliser la copie défensive , les constructeurs de copie (comme réponse @egaga) ou les méthodes d'usine statiques .
clone()
méthode publique , mais que vous ne connaissez pas le type de l'objet au moment de la compilation, vous avez un problème. Java a une interface appeléeCloneable
. En pratique, nous devons implémenter cette interface si nous voulons créer un objetCloneable
.Object.clone
est protégé , nous devons donc le remplacer par une méthode publique pour qu'il soit accessible.clone()
méthode de toutes les variables d'objet membre effectue également une copie en profondeur, cela est trop risqué pour une hypothèse. Vous devez contrôler le code dans toutes les classes.Par exemple, org.apache.commons.lang.SerializationUtils aura une méthode pour Deep clone utilisant la sérialisation ( Source ). Si nous devons cloner Bean, il existe deux méthodes utilitaires dans org.apache.commons.beanutils ( Source ).
cloneBean
clonera un bean en fonction des getters et setters de propriété disponibles, même si la classe de bean elle-même n'implémente pas Cloneable.copyProperties
copiera les valeurs de propriété du bean d'origine vers le bean de destination dans tous les cas où les noms de propriété sont identiques.la source
Dans le package,
import org.apache.commons.lang.SerializationUtils;
il y a une méthode:Exemple:
la source
Serializable
Suivez juste comme ci-dessous:
et partout où vous voulez obtenir un autre objet, effectuez simplement le clonage. par exemple:
la source
Pourquoi n'y a-t-il pas de réponse pour utiliser l'API Reflection?
C'est vraiment simple.
EDIT: inclure un objet enfant via la récursivité
la source
Class A { B child; } Class B{ A parent; }
class car { car car = new car(); }
J'utilise la bibliothèque JSON de Google pour la sérialiser, puis je crée une nouvelle instance de l'objet sérialisé. Il copie en profondeur avec quelques restrictions:
il ne peut pas y avoir de références récursives
il ne copiera pas les tableaux de types disparates
les tableaux et les listes doivent être tapés ou il ne trouvera pas la classe à instancier
vous devrez peut-être encapsuler des chaînes dans une classe que vous vous déclarez
J'utilise également cette classe pour enregistrer les préférences utilisateur, les fenêtres et autres éléments à recharger au moment de l'exécution. Il est très simple d'utilisation et efficace.
la source
Oui, vous faites simplement référence à l'objet. Vous pouvez cloner l'objet s'il implémente
Cloneable
.Consultez cet article wiki sur la copie d'objets.
Reportez-vous ici: Copie d'objets
la source
Ajouter
Cloneable
et ci-dessous du code à votre classeUtilisez ceci
clonedObject = (YourClass) yourClassObject.clone();
la source
Oui. Vous devez copier en profondeur votre objet.
la source
Cela fonctionne aussi. En supposant un modèle
Ajoutez d'abord
compile 'com.google.code.gson:gson:2.8.1'
à votre application> gradle & sync. alorsVous pouvez exclure l'utilisation d'un champ à l'aide d'un
transient
mot clé après le modificateur d'accès.Remarque: il s'agit d'une mauvaise pratique. Ne recommande pas non plus d'utiliser
Cloneable
ouJavaSerialization
c'est lent et cassé. Écrire le constructeur de copie pour les meilleures performances réf .Quelque chose comme
Statistiques de test de 90000 itérations: la
ligne
UserAccount clone = gson.fromJson(gson.toJson(aO), UserAccount.class);
dure 808 msLa ligne
UserAccount clone = new UserAccount(aO);
prend moins de 1 msConclusion: utilisez gson si votre patron est fou et que vous préférez la vitesse. Utilisez le deuxième constructeur de copie si vous préférez la qualité.
Vous pouvez également utiliser le plugin générateur de code de constructeur de copie dans Android Studio.
la source
Voici une explication décente de
clone()
si vous en avez besoin ...Ici: clone (méthode Java)
la source
Utilisez un utilitaire de clonage en profondeur:
Cela copiera en profondeur tout objet java, vérifiez-le sur https://github.com/kostaskougios/cloning
la source
Le clonage en profondeur est votre réponse, qui nécessite la mise en œuvre de l'
Cloneable
interface et le remplacement de laclone()
méthode.Tu l'appelleras comme ça
DummyBean dumtwo = dum.clone();
la source
dummy
, aString
, est immuable, vous n'avez pas besoin de le copierPour ce faire, vous devez cloner l'objet d'une manière ou d'une autre. Bien que Java ait un mécanisme de clonage, ne l'utilisez pas si vous n'en avez pas besoin. Créez une méthode de copie qui effectue le travail de copie pour vous, puis procédez comme suit:
Voici quelques conseils supplémentaires sur différentes techniques pour réaliser une copie.
la source
Autre que la copie explicite, une autre approche consiste à rendre l'objet immuable (aucune
set
ou d'autres méthodes de mutation). De cette façon, la question ne se pose jamais. L'immuabilité devient plus difficile avec des objets plus grands, mais cet autre aspect est qu'elle vous pousse dans la direction de la division en petits objets cohérents et composites.la source
Alternative à la méthode de copie du constructeur egaga . Vous avez probablement déjà un POJO, alors ajoutez simplement une autre méthode
copy()
qui retourne une copie de l'objet initialisé.Si vous en avez déjà un
DummyBean
et que vous souhaitez en obtenir une copie:Mais les deux fonctionnent bien, c'est à vous de décider ...
la source
la source
Vous pouvez copier en profondeur automatiquement avec XStream, depuis http://x-stream.github.io/ :
Ajoutez-le à votre projet (si vous utilisez maven)
alors
Avec cela, vous avez une copie sans avoir besoin d'implémenter une interface de clonage.
la source
java.beans.XMLEncoder
une API Java standard qui se sérialise également en XML (mais pas précisément à des fins de copie approfondie).et dans votre code:
la source
Passez l'objet que vous souhaitez copier et obtenez l'objet que vous souhaitez:
Maintenant, analysez l'
objDest
objet souhaité.Codage heureux!
la source
Vous pouvez essayer d'implémenter
Cloneable
et d'utiliser laclone()
méthode; cependant, si vous utilisez la méthode de clonage, vous devez - par défaut - toujours remplacerObject
lapublic Object clone()
méthode de.la source
Si vous pouvez ajouter une annotation au fichier source, un processeur d'annotation ou un générateur de code comme celui-ci peut être utilisé.
Une classe
DummyBeanBuilders
sera générée, qui a une méthode statiquedummyBeanUpdater
pour créer des copies superficielles, de la même manière que vous le feriez manuellement.la source
Utilisez
gson
pour dupliquer un objet.Supposons que j'ai un objet
person
.la source