Java Copy Constructor

1. Introduktion

En kopikonstruktør i en Java-klasse er en konstruktør, der opretter et objekt ved hjælp af et andet objekt i samme Java-klasse.

Det er nyttigt, når vi vil kopiere et komplekst objekt, der har flere felter, eller når vi vil lave en dyb kopi af et eksisterende objekt.

2. Sådan oprettes en kopi-konstruktør

For at oprette en kopikonstruktør kan vi først erklære en konstruktør, der tager et objekt af samme type som en parameter:

offentlig klassemedarbejder {privat int id; privat strengnavn; offentlig ansat (medarbejdermedarbejder) {}}

Derefter kopierer vi hvert felt af inputobjektet til den nye forekomst:

offentlig klassemedarbejder {privat int id; privat strengnavn; offentlig ansat (medarbejdermedarbejder) {this.id = medarbejder.id; dette.navn = medarbejder.navn; }}

Hvad vi har her er en lav kopi, hvilket er fint, da alle vores felter - en int og en Snor i dette tilfælde - er enten primitive eller uforanderlige typer.

Hvis Java-klassen har ændrede felter, kan vi i stedet lave en dyb kopi inde i sin kopibygger. Med en dyb kopi er det nyoprettede objekt uafhængigt af det originale, fordi vi opretter en særskilt kopi af hvert ændrede objekt:

offentlig klassemedarbejder {privat int id; privat strengnavn; privat Dato startdato; offentlig ansat (medarbejderansat) {this.id = medarbejder.id; dette.navn = medarbejder.navn; this.startDate = ny dato (medarbejder.startDate.getTime ()); }}

3. Copy Constructor vs. Clone

I Java kan vi også bruge klon metode til at oprette et objekt fra et eksisterende objekt. Kopikonstruktøren har dog nogle fordele i forhold til klon metode:

  1. Kopikonstruktøren er meget lettere at implementere. Vi behøver ikke at implementere Klonabel interface og håndtag CloneNotSupportedException.
  2. Det klon metode returnerer en generel Objekt reference. Derfor er vi nødt til at typecast det til den rigtige type.
  3. Vi kan ikke tildele en værdi til en endelig felt i klon metode. Vi kan dog gøre det i kopibyggeren.

4. Arvsproblemer

Kopikonstruktører i Java arves ikke af underklasser. Derfor, hvis vi forsøger at initialisere et underordnet objekt fra en overordnet klassereference, vi vil stå over for et castingsproblem når du kloner det med kopibyggeren.

For at illustrere dette problem, lad os først oprette en underklasse af Medarbejder og dets kopikonstruktør:

public class Manager udvider Medarbejder {private List directReports; // ... andre konstruktører offentlige Manager (Manager manager) {super (manager.id, manager.name, manager.startDate); this.directReports = directReports.stream () .collect (Collectors.toList ()); }} 

Derefter erklærer vi en Medarbejder variabel og instantier den med Manager konstruktør:

Medarbejderkilde = ny Manager (1, "Baeldung Manager", startDate, directReports);

Da referencetypen er Medarbejder, vi skal kaste det til Manager skriv, så vi kan bruge kopibyggeren til Manager klasse:

Medarbejderklon = ny Manager ((Manager) kilde);

Vi får muligvis ClassCastException ved kørsel, hvis inputobjektet ikke er en forekomst af Manager klasse.

En måde at undgå at kaste i kopikonstruktøren er at oprette en ny arvelig metode til begge klasser:

offentlig klassemedarbejder {offentlig medarbejderkopi () {returner ny medarbejder (dette); }} public class Manager udvider medarbejder {@Override public Employee copy () {return new Manager (this); }}

I hver klassemetode kalder vi dens kopikonstruktør med input af det her objekt. På denne måde kan vi garantere, at det genererede objekt er lig med det, der ringer op:

Medarbejderklon = source.copy ();

5. Konklusion

I denne vejledning viste vi, hvordan man opretter en kopikonstruktør med nogle kodeeksempler. Vi diskuterede også flere grunde til, at vi skulle undgå klon metode.

Copy constructor har et casting-problem, når vi bruger det til at klone et underordnet klasseobjekt, hvis referencetype er den overordnede klasse. Vi leverede en løsning til dette problem.

Som altid er kildekoden til vejledningen tilgængelig på GitHub.