Java clone – deep and shallow copy – copy constructors

Ein Klon ist eine exakte Kopie des Originals. In Java bedeutet dies im Wesentlichen die Möglichkeit, ein Objekt mit einem ähnlichen Status wie das ursprüngliche Objekt zu erstellen. Die java clone() -Methode stellt diese Funktionalität bereit.

In diesem Beitrag werden wir die meisten wichtigen Aspekte von Java Clone untersuchen.

Table of Contents1. What is clone?2. Java Cloneable interface and clone() method3. Shallow Copy4. Deep Copy5. Java Copy Constructors6. Deep copy with serialization7. Cloning using Apache commons8. Java clone best practices

Was ist Java clone?

Beim Klonen geht es also darum, die Kopie des ursprünglichen Objekts zu erstellen. Seine Wörterbuchbedeutung ist : „machen Sie eine identische Kopie von“.

Standardmäßig ist das Klonen von Java ‚Feld für Feld kopieren‘, dh die Objektklasse hat keine Ahnung von der Struktur der Klasse, für die die clone () -Methode aufgerufen wird.

Also, JVM, wenn zum Klonen aufgerufen, folgende Dinge tun:

  1. Wenn die Klasse nur primitive Datentyp Mitglieder dann eine völlig neue Kopie des Objekts wird erstellt und der Verweis auf die neue Objektkopie zurückgegeben werden.
  2. Wenn die Klasse Member eines beliebigen Klassentyps enthält, werden nur die Objektreferenzen auf diese Member kopiert, und daher beziehen sich die Member-Referenzen sowohl im ursprünglichen Objekt als auch im geklonten Objekt auf dasselbe Objekt.

Abgesehen vom obigen Standardverhalten können Sie dieses Verhalten jederzeit überschreiben und Ihr eigenes angeben. Dies geschieht mit Überschreiben clone() Methode. Mal sehen, wie es gemacht wird.

Java Cloneable Interface und clone() -Methode

Jede Sprache, die das Klonen von Objekten unterstützt, hat ihre eigenen Regeln und Java auch. Wenn eine Klasse in Java das Klonen unterstützen muss, muss sie Folgendes tun:

  1. Sie müssen die Cloneable Schnittstelle implementieren.
  2. Sie müssen die clone() -Methode aus der Objektklasse überschreiben.

Lesen Sie mehr: Cloneable Schnittstelle ist in Java gebrochen

Java-Dokumente über clone() Methode sind unten angegeben (formatiert und extrahieren).

  1. Die erste Anweisung garantiert, dass das geklonte Objekt eine separate Speicheradresszuweisung hat.
  2. Die zweite Anweisung legt nahe, dass originale und geklonte Objekte denselben Klassentyp haben sollten, dies ist jedoch nicht obligatorisch.
  3. Die dritte Anweisung legt nahe, dass originale und geklonte Objekte mit der equals() -Methode gleich sein sollten, dies ist jedoch nicht obligatorisch.

Lassen Sie uns Java clone anhand eines Beispiels verstehen. Unsere erste Klasse ist Employee Klasse mit 3 Attributen – idname und department.

Department Klasse hat zwei Attribute – id und name.

Wenn wir also die Employee-Klasse klonen müssen, müssen wir so etwas tun.

Großartig, wir haben das Employee Objekt erfolgreich geklont. Denken Sie jedoch daran, dass wir zwei Verweise auf dasselbe Objekt haben und jetzt beide den Status des Objekts in verschiedenen Teilen der Anwendung ändern. Willst du sehen wie? Mal sehen.

Hoppla, geklonte Objektänderungen sind auch im Original sichtbar. Auf diese Weise können geklonte Objekte Chaos im System verursachen, wenn dies erlaubt ist. Jeder kann kommen und Ihre Anwendungsobjekte klonen und tun, was er will. Können wir das verhindern??

Die Antwort ist ja, wir können. Wir können dies verhindern, indem wir Java Deep Copy erstellen und Kopierkonstruktoren verwenden. Wir werden später in diesem Beitrag mehr darüber erfahren. Lassen Sie uns zuerst sehen, was Deep Cloning und Shallow Cloning in Java sind.

Java Shallow Copy

Shallow clone ist eine „Standardimplementierung“ in Java. Wenn Sie in der überschriebenen clone -Methode nicht alle Objekttypen (keine Grundelemente) klonen, erstellen Sie eine flache Kopie.

Alle obigen Beispiele sind nur von flacher Kopie, weil wir das Department Objekt nicht auf Employee Klasse clone Methode geklont haben. Nun werde ich zum nächsten Abschnitt übergehen, wo wir das Deep Cloning sehen werden.

Java Deep Copy

Deep Clone ist in den meisten Fällen das gewünschte Verhalten. In der tiefen Kopie erstellen wir einen Klon, der unabhängig vom ursprünglichen Objekt ist, und Änderungen am geklonten Objekt sollten sich nicht auf das ursprüngliche Objekt auswirken.

Mal sehen, wie Deep Copy in Java erstellt wird.

Ich habe die Employee Klassen clone() Methode geändert und die folgende clone Methode in Department Klasse hinzugefügt.

Wenn Sie nun unseren Kloncode testen, erhalten Sie das gewünschte Ergebnis und der Name der Abteilung wird nicht geändert.

Hier wirkt sich das Ändern des Status des geklonten Objekts nicht auf das ursprüngliche Objekt aus.

So tiefes Klonen erfordert die Erfüllung der folgenden Regeln –

  • Keine Notwendigkeit, Primitive separat zu kopieren.
  • Alle Mitgliedsklassen in der ursprünglichen Klasse sollten das Klonen unterstützen und in der Klonmethode der ursprünglichen Klasse im Kontext super.clone() für alle Mitgliedsklassen aufrufen.
  • Wenn eine Mitgliedsklasse das Klonen nicht unterstützt, muss in der Klonmethode eine neue Instanz dieser Mitgliedsklasse erstellt und alle ihre Attribute nacheinander in ein neues Mitgliedsklassenobjekt kopiert werden. Dieses neue Mitgliedsklassenobjekt wird im geklonten Objekt festgelegt.

Lesen Sie mehr: Tiefes Klonen mit In-Memory-Serialisierung

Java-Kopierkonstruktoren

Kopierkonstruktoren sind spezielle Konstruktoren in einer Klasse, die Argumente für ihren eigenen Klassentyp verwenden. Wenn Sie also eine Instanz der Klasse an den Kopierkonstruktor übergeben, gibt der Konstruktor eine neue Instanz der Klasse mit Werten zurück, die von der Argumentinstanz kopiert wurden. Es hilft Ihnen, Objekt mit Cloneable Schnittstelle zu klonen.

Lets see this in example:

public class PointOne {private Integer x;private Integer y;public PointOne(PointOne point){this.x = point.x;this.y = point.y;}}

Diese Methode sieht einfach aus und es ist bis kommt Vererbung. Wenn Sie eine Klasse definieren, indem Sie die obige Klasse erweitern, müssen Sie dort auch einen ähnlichen Konstruktor definieren. In der untergeordneten Klasse müssen Sie untergeordnete spezifische Attribute kopieren und das Argument an den Konstruktor der Superklasse übergeben. Mal sehen wie?

Also, geht es uns jetzt gut? Nein. Das Problem bei der Vererbung besteht darin, dass das genaue Verhalten nur zur Laufzeit identifiziert wird. Also, in unserem Fall, wenn eine Klasse die Instanz von PointTwo im Konstruktor von PointOne .

In diesem Fall erhalten Sie die Instanz von PointOne im Gegenzug, wo Sie die Instanz von PointTwo als Argument übergeben haben. Sehen wir uns das im Code an:

Eine andere Möglichkeit, einen Kopierkonstruktor zu erstellen, besteht darin, statische Factory-Methoden zu haben. Sie nehmen den Klassentyp als Argument und erstellen eine neue Instanz mit einem anderen Konstruktor der Klasse. Dann kopieren diese Factory-Methoden alle Statusdaten in die neue Klasseninstanz, die gerade im vorherigen Schritt erstellt wurde, und geben diese aktualisierte Instanz zurück.

Java Deep Copy mit Serialisierung

Serialisierung ist eine weitere einfache Möglichkeit des Deep Cloning. Bei dieser Methode serialisieren Sie einfach das zu klonende Objekt und de-serialisieren es. Offensichtlich sollte das Objekt, das geklont werden muss, die Serializable Schnittstelle implementieren.

Bevor ich weitergehe, sollte ich darauf hinweisen, dass diese Technik nicht leichtfertig angewendet werden sollte.

  1. Zunächst einmal ist die Serialisierung enorm teuer. Es könnte leicht hundertmal teurer sein als die clone() Methode.
  2. Zweitens sind nicht alle Objekte Serializable .
  3. Drittens ist es schwierig, eine Klasse Serializable zu erstellen, und nicht auf alle Klassen kann man sich verlassen, um es richtig zu machen.

Lesen Sie mehr: Eine Anleitung zur Implementierung der Serialisierung in Java

Java clone – SerializationUtils

In Apache commons, SerializationUtils Klasse hat auch Utility-Funktion für tiefes Klonen. Wenn Sie interessiert sind, folgen Sie den offiziellen Dokumenten.

<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.7</version></dependency>
SomeObject cloned = org.apache.commons.lang.SerializationUtils.clone(someObject);

Java clone Best Practices

  1. Wenn Sie nicht wissen, ob Sie die clone() Methode einer bestimmten Klasse aufrufen können, da Sie nicht sicher sind, ob sie in dieser Klasse implementiert ist, können Sie überprüfen, ob die Klasse eine Instanz von “ Cloneable“ Schnittstelle wie folgt.
    if(obj1 instanceof Cloneable){ obj2 = obj1.clone();}//Dont do this. Cloneable dont have any methodsobj2 = (Cloneable)obj1.clone();
  2. Für das zu klonende Objekt wird kein Konstruktor aufgerufen. Daher liegt es in Ihrer Verantwortung, sicherzustellen, dass alle Mitglieder richtig eingestellt wurden. Wenn Sie die Anzahl der Objekte im System verfolgen, indem Sie den Aufruf von Konstruktoren zählen, haben Sie einen neuen zusätzlichen Platz, um den Zähler zu erhöhen.

Ich hoffe, dass dieser Beitrag eine Auffrischung für Sie war und Ihnen hilft, mehr Informationen über die Java 8-Klonmethode und deren korrekte Verwendung zu erhalten. Es wird auch bei der Beantwortung von Java Clone Interviewfragen helfen.

Viel Spaß beim Lernen !!

War dieser Beitrag hilfreich?

Lassen Sie uns wissen, ob Ihnen der Beitrag gefallen hat. Nur so können wir uns verbessern.
Ja
Nein

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.