Grundlegend: Objektkopieren in Java.
Angenommen, ein Objekt - obj1
, das zwei Objekte enthält, containedObj1 und containedObj2.
flaches Kopieren:
Flaches Kopieren erstellt eine neue Instanz
derselben Klasse und kopiert alle Felder in die neue Instanz und gibt sie zurück. Die Object-Klasse bietet eine clone
-Methode und unterstützt das flache Kopieren.
Tiefes Kopieren:
Ein tiefes Kopieren erfolgt, wenn ein Objekt zusammen mit den Objekten, auf die es verweist, kopiert wird. Im folgenden Bild wird obj1
nach einem tiefen Kopieren gezeigt. Nicht nur wurde obj1
kopiert, sondern auch die Objekte darin wurden kopiert. Wir können Java Object Serialization
verwenden, um ein tiefes Kopieren durchzuführen. Leider hat dieser Ansatz auch einige Probleme (detaillierte Beispiele).
![Bildbeschreibung hier eingeben]()
Mögliche Probleme:
clone
ist schwierig korrekt zu implementieren.
Es ist besser, Defensive Copying, Kopierkonstruktoren (wie in der Antwort von @egaga) oder statische Fabrikmethoden zu verwenden.
-
Wenn Sie ein Objekt haben, von dem Sie wissen, dass es eine öffentliche clone()
-Methode hat, aber Sie den Typ des Objekts zur Kompilierzeit nicht kennen, dann haben Sie ein Problem. Java hat ein Interface namens Cloneable
. Praktisch gesehen sollten wir dieses Interface implementieren, wenn wir ein Objekt Cloneable
machen wollen. Object.clone
ist protected, daher müssen wir es mit einer öffentlichen Methode überschreiben, damit es zugänglich ist.
-
Ein weiteres Problem entsteht, wenn wir versuchen, ein tiefes Kopieren eines komplexen Objekts durchzuführen. Angenommen, die clone()
-Methode aller Objektvariablen für Mitglieder führt ebenfalls ein tiefes Kopieren durch, dies ist eine zu riskante Annahme. Sie müssen den Code in allen Klassen kontrollieren.
Zum Beispiel wird org.apache.commons.lang.SerializationUtils eine Methode für das Tiefe Klonen mit Serialisierung haben (Quelle). Wenn wir ein Bean klonen müssen, gibt es ein paar Hilfsmethoden in org.apache.commons.beanutils (Quelle).
cloneBean
wird ein Bean auf der Grundlage der verfügbaren Eigenschaften-Getter und -Setter klonen, auch wenn die Bean-Klasse selbst nicht Cloneable implementiert.
copyProperties
wird Eigenschaftswerte vom Ursprungs-Bean auf das Ziel-Bean kopieren, wenn die Eigenschaftsnamen übereinstimmen.