logo

Metoda Clone() v Javi

Kloniranje predmeta se nanaša na ustvarjanje natančne kopije predmeta. Ustvari nov primerek razreda trenutnega objekta in inicializira vsa njegova polja z natančno vsebino ustreznih polj tega objekta.

Metode za izvajanje kloniranja objektov v Javi

Obstajajo 3 metode za ustvarjanje kloniranja predmetov v Javi, ki so omenjene spodaj:

  1. Uporaba operatorja dodelitve za ustvarjanje kopije referenčne spremenljivke
  2. Ustvarjanje kopije z metodo clone().
  3. Uporaba metode clone() – Deep Copy

1. Uporaba operatorja dodelitve za ustvarjanje a kopija referenčna spremenljivka

V Javi ni operaterja za ustvarjanje kopije predmeta. Za razliko od C++ bo v Javi, če uporabimo operator dodelitve, ustvaril kopijo referenčne spremenljivke in ne objekta. To je mogoče pojasniti s primerom. Naslednji program prikazuje isto.



Spodaj je izvedba zgornje teme:

Java




igralec govinda
// Java program to demonstrate that assignment operator> // only creates a new reference to same object> import> java.io.*;> > // A test class whose objects are cloned> class> Test {> >int> x, y;> >Test()> >{> >x =>10>;> >y =>20>;> >}> }> > // Driver Class> class> Main {> >public> static> void> main(String[] args)> >{> >Test ob1 =>new> Test();> > >System.out.println(ob1.x +>' '> + ob1.y);> > >// Creating a new reference variable ob2> >// pointing to same address as ob1> >Test ob2 = ob1;> > >// Any change made in ob2 will> >// be reflected in ob1> >ob2.x =>100>;> > >System.out.println(ob1.x +>' '> + ob1.y);> >System.out.println(ob2.x +>' '> + ob2.y);> >}> }>

>

fmovies
>

Izhod

10 20 100 20 100 20>

2. Ustvarjanje kopije z metodo clone().

Razred, katerega kopija objekta naj bo izdelana, mora imeti v sebi ali v enem od svojih nadrejenih razredov javno metodo kloniranja.

  • Vsak razred, ki izvaja clone(), bi moral poklicati super.clone(), da pridobi referenco kloniranega objekta.
  • Razred mora implementirati tudi vmesnik java.lang.Cloneable, katerega klon objekta želimo ustvariti, sicer bo vrgel CloneNotSupportedException, ko bo metoda kloniranja poklicana na objektu tega razreda.

Sintaksa:

protected Object clone() throws CloneNotSupportedException>

i) Uporaba metode clone() - plitka kopija

Opomba – V spodnjem primeru kode metoda clone() ustvari popolnoma nov objekt z drugačno vrednostjo hashCode, kar pomeni, da je na ločeni pomnilniški lokaciji. Ker pa je Testni objekt c znotraj Test2, so primitivni tipi dosegli globoko kopijo, vendar je ta Testni objekt c še vedno v skupni rabi med t1 in t2. Da bi to odpravili, izrecno naredimo globoko kopijo za objektno spremenljivko c, o kateri bomo razpravljali kasneje.

Java




// A Java program to demonstrate> // shallow copy using clone()> import> java.util.ArrayList;> > // An object reference of this class is> // contained by Test2> class> Test {> >int> x, y;> }> > // Contains a reference of Test and> // implements clone with shallow copy.> class> Test2>implements> Cloneable {> >int> a;> >int> b;> >Test c =>new> Test();> >public> Object clone()>throws> CloneNotSupportedException> >{> >return> super>.clone();> >}> }> > // Driver class> public> class> Main {> >public> static> void> main(String args[])> >throws> CloneNotSupportedException> >{> >Test2 t1 =>new> Test2();> >t1.a =>10>;> >t1.b =>20>;> >t1.c.x =>30>;> >t1.c.y =>40>;> > >Test2 t2 = (Test2)t1.clone();> > >// Creating a copy of object t1> >// and passing it to t2> >t2.a =>100>;> > >// Change in primitive type of t2 will> >// not be reflected in t1 field> >t2.c.x =>300>;> > >// Change in object type field will be> >// reflected in both t2 and t1(shallow copy)> >System.out.println(t1.a +>' '> + t1.b +>' '> + t1.c.x> >+>' '> + t1.c.y);> >System.out.println(t2.a +>' '> + t2.b +>' '> + t2.c.x> >+>' '> + t2.c.y);> >}> }>

>

>

Izhod

10 20 300 40 100 20 300 40>

V zgornjem primeru t1.clone vrne plitvo kopijo predmeta t1. Za pridobitev globoke kopije predmeta je treba po pridobitvi kopije narediti določene spremembe v metodi kloniranja.

ii) Uporaba metode clone() – globoka kopija

  • Če želimo ustvariti globoko kopijo objekta X in jo postaviti v nov objekt Y, se ustvari nova kopija vseh polj predmetov, na katere se sklicuje, in ti sklici se postavijo v objekt Y. To pomeni vse spremembe v poljih predmetov, na katere se sklicuje, v objektu X ali Y se bosta odražala samo v tem predmetu in ne v drugem. V spodnjem primeru ustvarimo globoko kopijo predmeta.
  • Globoka kopija kopira vsa polja in naredi kopije dinamično dodeljenega pomnilnika, na katerega kažejo polja. Globoka kopija se pojavi, ko se objekt kopira skupaj s predmeti, na katere se nanaša.

Java


funkcije arduina



niz nadomesti vso javo

// A Java program to demonstrate> // deep copy using clone()> > // An object reference of this> // class is contained by Test2> class> Test {> >int> x, y;> }> > // Contains a reference of Test and> // implements clone with deep copy.> class> Test2>implements> Cloneable {> >int> a, b;> > >Test c =>new> Test();> > >public> Object clone()>throws> CloneNotSupportedException> >{> >// Assign the shallow copy to> >// new reference variable t> >Test2 t = (Test2)>super>.clone();> > >// Creating a deep copy for c> >t.c =>new> Test();> >t.c.x = c.x;> >t.c.y = c.y;> > >// Create a new object for the field c> >// and assign it to shallow copy obtained,> >// to make it a deep copy> >return> t;> >}> }> > public> class> Main {> >public> static> void> main(String args[])> >throws> CloneNotSupportedException> >{> >Test2 t1 =>new> Test2();> >t1.a =>10>;> >t1.b =>20>;> >t1.c.x =>30>;> >t1.c.y =>40>;> > >Test2 t3 = (Test2)t1.clone();> >t3.a =>100>;> > >// Change in primitive type of t2 will> >// not be reflected in t1 field> >t3.c.x =>300>;> > >// Change in object type field of t2 will> >// not be reflected in t1(deep copy)> >System.out.println(t1.a +>' '> + t1.b +>' '> + t1.c.x> >+>' '> + t1.c.y);> >System.out.println(t3.a +>' '> + t3.b +>' '> + t3.c.x> >+>' '> + t3.c.y);> >}> }>

>

>

Izhod

10 20 30 40 100 20 300 40>

V zgornjem primeru lahko vidimo, da je bil nov objekt za razred Test dodeljen za kopiranje predmeta, ki bo vrnjen metodi kloniranja. Zaradi tega bo t3 pridobil globoko kopijo objekta t1. Torej kakršne koli spremembe, ki jih je t3 naredil v poljih predmeta 'c', se ne bodo odražale v t1.

Globoko kopiranje proti plitkemu kopiranju

Obstajajo določene razlike med uporabo clone() kot globoke kopije in tiste kot plitke kopije, kot je navedeno spodaj:

  • Plitka kopija je metoda kopiranja predmeta in ji privzeto sledi pri kloniranju. Pri tej metodi se polja starega predmeta X prekopirajo v novi objekt Y. Med kopiranjem polja vrste objekta se referenca kopira v Y, tj. objekt Y bo kazal na isto lokacijo, kot jo je pokazal X. Če vrednost polja je primitivni tip kopira vrednost primitivnega tipa.
  • Zato se bodo vse spremembe, narejene v referenčnih objektih v objektu X ali Y, odražale v drugih objektih.

Plitke kopije so poceni in preproste za izdelavo. V zgornjem primeru smo ustvarili plitvo kopijo the predmet.

Zakaj uporabljati metodo clone() oz Prednosti metode kloniranja

  • Če uporabimo operator dodelitve za dodelitev sklica na objekt drugi referenčni spremenljivki, bo kazal na isto lokacijo naslova starega objekta in ne bo ustvarjena nova kopija objekta. Zaradi tega se bodo vse spremembe referenčne spremenljivke odražale v izvirnem objektu.
  • Če uporabljamo kopirni konstruktor, potem moramo eksplicitno prekopirati vse podatke, tj. eksplicitno moramo dodeliti vsa polja razreda v konstruktorju. Toda pri metodi kloniranja to delo ustvarjanja nove kopije opravi metoda sama. Da bi se izognili dodatni obdelavi, uporabljamo kloniranje objektov.