Java Kopiraj konstruktor

1. Uvod

Konstruktor kopiranja u Java klasi je konstruktor koji stvara objekt koristeći drugi objekt iste Java klase.

To je korisno kada želimo kopirati složeni objekt koji ima nekoliko polja ili kada želimo napraviti dubinsku kopiju postojećeg objekta.

2. Kako stvoriti konstruktor kopija

Da bismo stvorili konstruktor kopije, prvo možemo deklarirati konstruktor koji uzima objekt istog tipa kao parametar:

zaposlenik u javnoj klasi {private int id; privatni naziv niza; javni zaposlenik (zaposlenik) {}}

Zatim kopiramo svako polje ulaznog objekta u novu instancu:

zaposlenik u javnoj klasi {private int id; privatni naziv niza; javni zaposlenik (zaposlenik zaposlenik) {this.id = worker.id; this.name = zaposlenik.ime; }}

Ono što ovdje imamo je plitka kopija, što je u redu jer su sva naša polja - an int i a Niz u ovom slučaju - jesu li primitivni ili nepromjenjivi tipovi.

Ako Java klasa ima promjenjiva polja, tada umjesto toga možemo napraviti duboka kopija unutar svog konstruktora kopija. Dubinskom kopijom novostvoreni objekt neovisan je od izvornog jer stvaramo zasebnu kopiju svakog promjenjivog objekta:

zaposlenik u javnoj klasi {private int id; privatni naziv niza; privatni Datum datum početka; javni zaposlenik (zaposlenik zaposlenik) {this.id = worker.id; this.name = zaposlenik.ime; this.startDate = novi datum (worker.startDate.getTime ()); }}

3. Kopiraj konstruktor u odnosu na Klon

U Javi također možemo koristiti klon metoda za stvaranje objekta od postojećeg objekta. Međutim, konstruktor kopija ima neke prednosti u odnosu na klon metoda:

  1. Konstruktor kopija je puno jednostavniji za implementaciju. Ne trebamo provoditi Klonirajući sučelje i ručka CloneNotSupportedException.
  2. The klon metoda vraća općenito Objekt referenca. Stoga ga moramo ukucati u odgovarajući tip.
  3. Ne možemo dodijeliti vrijednost a konačni polje u klon metoda. Međutim, to možemo učiniti u konstruktoru kopiranja.

4. Pitanja nasljeđivanja

Konstruktori kopiranja u Javi nisu nasljedni po podklasama. Stoga, ako pokušamo inicijalizirati podređeni objekt iz reference roditeljske klase, suočit ćemo se s problemom kastinga pri kloniranju s konstruktorom kopija.

Da bismo ilustrirali ovaj problem, prvo stvorimo podrazred od Zaposlenik i njegov konstruktor kopija:

upravitelj javne klase proširuje Employee {private list directReports; // ... ostali konstruktori public Manager (Manager manager) {super (manager.id, manager.name, manager.startDate); this.directReports = directReports.stream () .collect (Collectors.toList ()); }} 

Zatim proglašavamo Zaposlenik varijablu i instancirajte je s Menadžer konstruktor:

Izvor zaposlenika = novi upravitelj (1, "Baeldung Manager", startDate, directReports);

Budući da je referentni tip Zaposlenik, moramo ga baciti na Menadžer tipa kako bismo mogli koristiti konstruktor kopiranja Menadžer razred:

Klon zaposlenika = novi upravitelj (((Manager) izvor);

Možda ćemo dobiti ClassCastException u vrijeme izvođenja ako ulazni objekt nije instanca Menadžer razred.

Jedan od načina da se izbjegne lijevanje u konstruktoru kopiranja je stvaranje nove nasljedne metode za obje klase:

javni razred Zaposlenik {public Employee copy () {return new Employee (this); }} upravitelj javne klase proširuje zaposlenika {@Override javna kopija zaposlenika () {return new Manager (this); }}

U svakoj metodi klase nazivamo njezin konstruktor kopija s unosom ovaj objekt. Na taj način možemo jamčiti da je generirani objekt jednak pozivatelju:

Klon zaposlenika = source.copy ();

5. Zaključak

U ovom uputstvu pokazali smo kako stvoriti konstruktor kopije s nekoliko primjera koda. Također, razgovarali smo o nekoliko razloga zašto bismo trebali izbjegavati klon metoda.

Konstruktor kopiranja ima problem s lijevanjem kada ga koristimo za kloniranje objekta podređene klase čiji je referentni tip roditeljska klasa. Dali smo jedno rješenje za ovaj problem.

Kao i uvijek, izvorni kôd vodiča dostupan je na GitHub-u.