Betrachten Sie den folgenden Code:
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'
Also, ich möchte , dass die kopieren dum
zu dumtwo
und ändern , dum
ohne die Auswirkungen auf dumtwo
. Aber der obige Code macht das nicht. Wenn ich etwas dum
ändere, geschieht die gleiche Änderung dumtwo
auch in.
Ich denke, wenn ich sage dumtwo = dum
, kopiert Java nur die Referenz . Gibt es eine Möglichkeit, eine neue Kopie zu erstellen dum
und dieser zuzuweisen dumtwo
?
Grundlegend: Objektkopieren in Java.
Lassen Sie uns eine objekt- Angenommen
obj1
, dass enthält zwei Objekte, containedObj1 und containedObj2 .Flaches Kopieren: Beim
flachen Kopieren wird ein neues
instance
Feld derselben Klasse erstellt, alle Felder werden in die neue Instanz kopiert und zurückgegeben. Die Objektklasse bietet eineclone
Methode und unterstützt das flache Kopieren.Tiefes Kopieren:
Eine tiefe Kopie erfolgt, wenn ein Objekt zusammen mit den Objekten kopiert wird, auf die es sich bezieht . Das folgende Bild zeigt,
obj1
nachdem eine tiefe Kopie darauf durchgeführt wurde. Es wurde nicht nurobj1
kopiert , sondern auch die darin enthaltenen Objekte wurden kopiert. Wir können verwendenJava Object Serialization
, um eine tiefe Kopie zu erstellen. Leider weist dieser Ansatz auch einige Probleme auf ( detaillierte Beispiele ).Mögliche Probleme: Die
clone
korrekte Implementierung ist schwierig.Es ist besser, defensives Kopieren , Kopierkonstruktoren (als @ egaga-Antwort) oder statische Factory-Methoden zu verwenden .
clone()
Methode hat, aber den Typ des Objekts zur Kompilierungszeit nicht kennen, liegt ein Problem vor. Java hat eine Schnittstelle namensCloneable
. In der Praxis sollten wir diese Schnittstelle implementieren, wenn wir ein Objekt erstellen möchtenCloneable
.Object.clone
ist geschützt , daher müssen wir es mit einer öffentlichen Methode überschreiben, damit es zugänglich ist.clone()
Methode aller Mitgliedsobjektvariablen kopiert auch tief, dies ist zu riskant für eine Annahme. Sie müssen den Code in allen Klassen steuern.Zum Beispiel hat org.apache.commons.lang.SerializationUtils eine Methode für Deep Clone unter Verwendung der Serialisierung ( Quelle ). Wenn wir Bean klonen müssen, gibt es in org.apache.commons.beanutils ( Source ) einige Dienstprogrammmethoden .
cloneBean
Klont eine Bean basierend auf den verfügbaren Eigenschafts-Gettern und -Setzern, auch wenn die Bean-Klasse selbst Cloneable nicht implementiert.copyProperties
Kopiert Eigenschaftswerte von der Ursprungs-Bean in die Ziel-Bean für alle Fälle, in denen die Eigenschaftsnamen identisch sind.quelle
Im Paket
import org.apache.commons.lang.SerializationUtils;
gibt es eine Methode:Beispiel:
quelle
Serializable
Folgen Sie einfach wie folgt:
und wo immer Sie ein anderes Objekt erhalten möchten, führen Sie einfach das Klonen durch. z.B:
quelle
Warum gibt es keine Antwort für die Verwendung der Reflection-API?
Es ist wirklich einfach.
BEARBEITEN: Untergeordnetes Objekt über Rekursion einschließen
quelle
Class A { B child; } Class B{ A parent; }
class car { car car = new car(); }
Ich verwende die JSON-Bibliothek von Google, um sie zu serialisieren, und erstelle dann eine neue Instanz des serialisierten Objekts. Es kopiert tief mit ein paar Einschränkungen:
Es kann keine rekursiven Referenzen geben
Es werden keine Arrays unterschiedlicher Typen kopiert
Arrays und Listen sollten eingegeben werden, da sonst die zu instanziierende Klasse nicht gefunden wird
Möglicherweise müssen Sie Zeichenfolgen in einer Klasse kapseln, die Sie selbst deklarieren
Ich benutze diese Klasse auch, um Benutzereinstellungen, Fenster und so weiter zu speichern, um zur Laufzeit neu geladen zu werden. Es ist sehr einfach zu bedienen und effektiv.
quelle
Ja, Sie verweisen nur auf das Objekt. Sie können das Objekt klonen, wenn es implementiert wird
Cloneable
.Lesen Sie diesen Wiki-Artikel über das Kopieren von Objekten.
Siehe hier: Objektkopieren
quelle
Fügen Sie
Cloneable
Ihrer Klasse Code hinzu und darunterBenutze das
clonedObject = (YourClass) yourClassObject.clone();
quelle
Ja. Sie müssen Ihr Objekt tief kopieren .
quelle
Das funktioniert auch. Modell annehmen
compile 'com.google.code.gson:gson:2.8.1'
Fügen Sie zuerst Ihrer App> gradle & sync hinzu. DannSie können die Verwendung eines Felds ausschließen, indem Sie das
transient
Schlüsselwort nach dem Zugriffsmodifikator verwenden.Hinweis: Dies ist eine schlechte Praxis. Auch nicht empfehlen zu verwenden
Cloneable
oderJavaSerialization
es ist langsam und kaputt. Schreib Copykonstruktor für die beste Leistung ref .Etwas wie
Teststatistik der 90000-Iteration: Die
Linie
UserAccount clone = gson.fromJson(gson.toJson(aO), UserAccount.class);
dauert 808 msDie Leitung
UserAccount clone = new UserAccount(aO);
dauert weniger als 1 msFazit: Verwenden Sie gson, wenn Ihr Chef verrückt ist und Sie Geschwindigkeit bevorzugen. Verwenden Sie den zweiten Kopierkonstruktor, wenn Sie Qualität bevorzugen.
Sie können auch das Plugin zum Kopieren des Konstruktorcode- Generators in Android Studio verwenden.
quelle
Hier ist eine anständige Erklärung,
clone()
ob Sie es am Ende brauchen ...Hier: Klon (Java-Methode)
quelle
Verwenden Sie ein Deep Cloning-Dienstprogramm:
Dadurch werden alle Java-Objekte tief kopiert. Überprüfen Sie sie unter https://github.com/kostaskougios/cloning
quelle
Deep Cloning ist Ihre Antwort, bei der die
Cloneable
Schnittstelle implementiert und dieclone()
Methode überschrieben werden muss.Sie werden es so nennen
DummyBean dumtwo = dum.clone();
quelle
dummy
, aString
, ist unveränderlich, Sie müssen es nicht kopierenDazu müssen Sie das Objekt auf irgendeine Weise klonen. Obwohl Java über einen Klonmechanismus verfügt, sollten Sie ihn nicht verwenden, wenn Sie dies nicht müssen. Erstellen Sie eine Kopiermethode, mit der die Kopie für Sie ausgeführt wird, und führen Sie dann Folgendes aus:
Hier finden Sie weitere Ratschläge zu verschiedenen Techniken zum Erstellen einer Kopie.
quelle
Abgesehen vom expliziten Kopieren besteht ein anderer Ansatz darin, das Objekt unveränderlich zu machen (keine
set
oder andere Mutatormethoden). Auf diese Weise stellt sich nie die Frage. Die Unveränderlichkeit wird bei größeren Objekten schwieriger, aber die andere Seite davon ist, dass sie Sie in die Richtung der Aufteilung in zusammenhängende kleine Objekte und Verbundwerkstoffe treibt.quelle
Alternative zu egagas Konstruktormethode zum Kopieren. Sie haben wahrscheinlich bereits ein POJO. Fügen Sie einfach eine andere Methode hinzu,
copy()
die eine Kopie des initialisierten Objekts zurückgibt.Wenn Sie bereits eine haben
DummyBean
und eine Kopie wünschen:Aber beides funktioniert gut, es liegt letztendlich an dir ...
quelle
quelle
Sie können mit XStream automatisch von http://x-stream.github.io/ tief kopieren :
Fügen Sie es Ihrem Projekt hinzu (wenn Sie maven verwenden)
Dann
Damit haben Sie eine Kopie, ohne dass Sie eine Klonschnittstelle implementieren müssen.
quelle
java.beans.XMLEncoder
einer Standard-Java-API, die auch in XML serialisiert wird (allerdings nicht genau für Deep-Copy-Zwecke).und in Ihrem Code:
quelle
Übergeben Sie das Objekt, das Sie kopieren möchten, und erhalten Sie das gewünschte Objekt:
Analysieren Sie nun das
objDest
gewünschte Objekt.Viel Spaß beim Codieren!
quelle
Sie können versuchen,
Cloneable
dieclone()
Methode zu implementieren und zu verwenden . aber wenn Sie die Klon - Methode Sie sollten - durch Standard - IMMER überschreibenObject
‚s -public Object clone()
Methode.quelle
Wenn Sie der Quelldatei eine Anmerkung hinzufügen können, kann ein Anmerkungsprozessor oder ein Codegenerator wie dieser verwendet werden.
Es
DummyBeanBuilders
wird eine Klasse generiert, die über eine statische MethodedummyBeanUpdater
zum Erstellen flacher Kopien verfügt, genauso wie Sie es manuell tun würden.quelle
Verwenden Sie
gson
für ein Objekt zu duplizieren.Gehe ich davon aus, ein Objekt haben
person
.Soquelle