Java Copy Constructor

1. Inleiding

Een kopieerconstructor in een Java-klasse is een constructor die maakt een object aan met een ander object van dezelfde Java-klasse.

Dat is handig als we een complex object met meerdere velden willen kopiëren, of als we een diepe kopie van een bestaand object willen maken.

2. Hoe u een kopieerconstructor kunt maken

Om een ​​kopieerconstructor te maken, kunnen we eerst een constructor declareren waaraan een object van hetzelfde type als een parameter moet voldoen:

openbare klasse Medewerker {privé int id; private String naam; openbare medewerker (medewerker medewerker) {}}

Vervolgens kopiëren we elk veld van het invoerobject naar de nieuwe instantie:

openbare klasse Medewerker {privé int id; private String naam; publieke medewerker (medewerker medewerker) {this.id = medewerker.id; this.name = medewerker.name; }}

Wat we hier hebben is een Oppervlakkige kopie, wat prima is omdat al onze velden - een int en een Draad in dit geval - zijn ofwel primitieve typen of onveranderlijke typen.

Als de Java-klasse veranderlijke velden heeft, kunnen we in plaats daarvan een diepe kopie in de kopieerconstructor. Met een diepe kopie is het nieuw gemaakte object onafhankelijk van het originele, omdat we een aparte kopie maken van elk veranderlijk object:

openbare klasse Medewerker {privé int id; private String naam; privé Datum startDate; publieke medewerker (medewerker medewerker) {this.id = medewerker.id; this.name = medewerker.name; this.startDate = nieuwe datum (employee.startDate.getTime ()); }}

3. Kopieer Constructor vs. kloon

In Java kunnen we ook de kloon methode om een ​​object te maken van een bestaand object. De kopieerconstructor heeft echter enkele voordelen ten opzichte van de kloon methode:

  1. De kopieerconstructor is veel gemakkelijker te implementeren. We hoeven het Te klonen interface en handvat CloneNotSupportedException.
  2. De kloon methode retourneert een algemeen Voorwerp referentie. Daarom moeten we het naar het juiste type typen.
  3. We kunnen geen waarde toekennen aan a laatste veld in het kloon methode. We kunnen dit echter doen in de kopieerconstructor.

4. Overervingskwesties

Kopieerconstructors in Java kunnen niet worden overgenomen door subklassen. Daarom, als we proberen een onderliggend object te initialiseren vanuit een verwijzing naar een bovenliggende klasse, we zullen een castingprobleem onder ogen zien bij het klonen met de kopieerconstructor.

Om dit probleem te illustreren, maken we eerst een subklasse van Werknemer en zijn kopieerconstructor:

public class Manager breidt Employee {private List directReports uit; // ... andere constructeurs openbare Manager (Manager manager) {super (manager.id, manager.name, manager.startDate); this.directReports = directReports.stream () .collect (Collectors.toList ()); }} 

Vervolgens verklaren we een Werknemer variabele en instantieer het met de Manager constructeur:

Bron werknemer = nieuwe Manager (1, "Baeldung Manager", startDate, directReports);

Omdat het referentietype is Werknemer, we moeten het casten Manager type zodat we de kopieerconstructor van de Manager klasse:

Werknemer kloon = nieuwe Manager ((Manager) bron);

We kunnen krijgen ClassCastException tijdens runtime als het invoerobject geen exemplaar is van Manager klasse.

Een manier om casten in de kopieerconstructor te voorkomen, is door een nieuwe overerfbare methode voor beide klassen te maken:

openbare klasse Medewerker {openbare Medewerker kopie () {retourneer nieuwe Medewerker (dit); }} public class Manager breidt Employee {@Override public Employee copy () {return new Manager (this) uit; }}

In elke klassemethode noemen we de kopieerconstructor met de invoer van dit voorwerp. Op deze manier kunnen we garanderen dat het gegenereerde object gelijk is aan het bellerobject:

Werknemer kloon = source.copy ();

5. Conclusie

In deze zelfstudie hebben we met enkele codevoorbeelden laten zien hoe u een kopieerconstructor kunt maken. We hebben ook verschillende redenen besproken waarom we de kloon methode.

Copy constructor heeft een casting-probleem wanneer we het gebruiken om een ​​kindklasseobject te klonen waarvan het referentietype de bovenliggende klasse is. We hebben een oplossing voor dit probleem geboden.

Zoals altijd is de broncode voor de tutorial beschikbaar op GitHub.