Java Copy Constructor

1. Einleitung

Ein Kopierkonstruktor in einer Java-Klasse ist ein Konstruktor, der ein Objekt mit einem anderen Objekt derselben Java-Klasse erstellt .

Dies ist hilfreich, wenn Sie ein komplexes Objekt mit mehreren Feldern kopieren oder eine tiefe Kopie eines vorhandenen Objekts erstellen möchten.

2. So erstellen Sie einen Kopierkonstruktor

Um einen Kopierkonstruktor zu erstellen, können wir zuerst einen Konstruktor deklarieren, der ein Objekt des gleichen Typs als Parameter verwendet:

public class Employee { private int id; private String name; public Employee(Employee employee) { } }

Dann kopieren wir jedes Feld des Eingabeobjekts in die neue Instanz:

public class Employee { private int id; private String name; public Employee(Employee employee) { this.id = employee.id; this.name = employee.name; } }

Was wir hier haben, ist eine flache Kopie , was in Ordnung ist, da alle unsere Felder - in diesem Fall ein int und ein String - entweder primitive Typen oder unveränderliche Typen sind.

Wenn die Java-Klasse veränderbare Felder hat, können wir stattdessen eine tiefe Kopie in ihrem Kopierkonstruktor erstellen. Bei einer tiefen Kopie ist das neu erstellte Objekt unabhängig vom ursprünglichen Objekt, da wir für jedes veränderbare Objekt eine eigene Kopie erstellen:

public class Employee { private int id; private String name; private Date startDate; public Employee(Employee employee) { this.id = employee.id; this.name = employee.name; this.startDate = new Date(employee.startDate.getTime()); } }

3. Kopieren Sie den Konstruktor gegen den Klon

In Java können wir auch die Klonmethode verwenden, um ein Objekt aus einem vorhandenen Objekt zu erstellen. Der Kopierkonstruktor hat jedoch einige Vorteile gegenüber der Klonmethode :

  1. Der Kopierkonstruktor ist viel einfacher zu implementieren. Wir brauchen nicht die zur Umsetzung klonbar Schnittstelle und Griff CloneNotSupportedException .
  2. Die Klonmethode gibt eine allgemeine Objektreferenz zurück . Daher müssen wir es auf den entsprechenden Typ typisieren.
  3. Wir können einem endgültigen Feld in der Klonmethode keinen Wert zuweisen . Dies können wir jedoch im Kopierkonstruktor tun.

4. Vererbungsprobleme

Kopierkonstruktoren in Java können nicht von Unterklassen vererbt werden. Wenn wir versuchen, ein untergeordnetes Objekt aus einer übergeordneten Klassenreferenz zu initialisieren, tritt daher beim Klonen mit dem Kopierkonstruktor ein Casting-Problem auf .

Um dieses Problem zu veranschaulichen, erstellen wir zunächst eine Unterklasse von Employee und seinem Kopierkonstruktor:

public class Manager extends Employee { private List directReports; // ... other constructors public Manager(Manager manager) { super(manager.id, manager.name, manager.startDate); this.directReports = directReports.stream() .collect(Collectors.toList()); } } 

Anschließend deklarieren wir eine Employee- Variable und instanziieren sie mit dem Manager- Konstruktor:

Employee source = new Manager(1, "Baeldung Manager", startDate, directReports);

Da der Referenztyp Employee ist , müssen wir ihn in den Manager- Typ umwandeln, damit wir den Kopierkonstruktor der Manager- Klasse verwenden können:

Employee clone = new Manager((Manager) source);

Wir können ClassCastException zur Laufzeit erhalten, wenn das Eingabeobjekt keine Instanz der Manager- Klasse ist.

Eine Möglichkeit, das Casting im Kopierkonstruktor zu vermeiden, besteht darin, eine neue vererbbare Methode für beide Klassen zu erstellen:

public class Employee { public Employee copy() { return new Employee(this); } } public class Manager extends Employee { @Override public Employee copy() { return new Manager(this); } }

In jeder Klassenmethode rufen wir ihren Kopierkonstruktor mit der Eingabe dieses Objekts auf. Auf diese Weise können wir garantieren, dass das generierte Objekt dem Aufruferobjekt entspricht:

Employee clone = source.copy();

5. Schlussfolgerung

In diesem Tutorial haben wir anhand einiger Codebeispiele gezeigt, wie ein Kopierkonstruktor erstellt wird. Außerdem diskutierten wir mehrere Gründe , warum wir das vermeiden sollte Klon - Methode.

Der Kopierkonstruktor hat ein Casting-Problem, wenn wir damit ein untergeordnetes Klassenobjekt klonen, dessen Referenztyp die übergeordnete Klasse ist. Wir haben eine Lösung für dieses Problem bereitgestellt.

Wie immer ist der Quellcode für das Tutorial auf GitHub verfügbar.