Objektkloning refererer til opprettelsen av en eksakt kopi av et objekt. Den oppretter en ny forekomst av klassen til det gjeldende objektet og initialiserer alle feltene med nøyaktig innholdet i de tilsvarende feltene til dette objektet.
Metoder for å utføre objektkloning i Java
Det er 3 metoder for å lage objektkloning i Java som er nevnt nedenfor:
- Bruke Assignment Operator for å lage en kopi av referansevariabelen
- Opprette en kopi ved å bruke klone()-metoden
- Bruk av klone()-metoden – Deep Copy
1. Bruke Assignment Operator for å lage en kopi av referansevariabel
I Java er det ingen operatør for å lage en kopi av et objekt. I motsetning til C++, i Java, hvis vi bruker tildelingsoperatoren, vil den lage en kopi av referansevariabelen og ikke objektet. Dette kan forklares ved å ta et eksempel. Følgende program viser det samme.
Nedenfor er implementeringen av emnet ovenfor:
Java
// 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);> >}> }> |
>
>Produksjon
10 20 100 20 100 20>
2. Opprette en kopi ved å bruke klone()-metoden
Klassen hvis objektets kopi skal lages, må ha en offentlig klonemetode i den eller i en av dens overordnede klasser.
- Hver klasse som implementerer clone() bør kalle super.clone() for å få den klonede objektreferansen.
- Klassen må også implementere java.lang.Cloneable grensesnitt hvis objektklone vi ønsker å lage, ellers vil den kaste CloneNotSupportedException når klonemetoden kalles på den klassens objekt.
Syntaks:
protected Object clone() throws CloneNotSupportedException>
i) Bruk av clone()-metoden -Shallow Copy
Merk – I kodeeksemplet nedenfor oppretter clone()-metoden et helt nytt objekt med en annen hashCode-verdi, som betyr at den er på en separat minneplassering. Men på grunn av at testobjektet c er inne i Test2, har de primitive typene oppnådd dyp kopi, men dette testobjektet c er fortsatt delt mellom t1 og t2. For å overvinne det gjør vi eksplisitt en dyp kopi for objektvariabel c, som diskuteres senere.
linux oppgavebehandling
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);> >}> }> |
>
>Produksjon
10 20 300 40 100 20 300 40>
I eksemplet ovenfor returnerer t1.clone den grunne kopien av objektet t1. For å få en dyp kopi av objektet må visse modifikasjoner gjøres i klonemetoden etter å ha fått kopien.
ii) Bruk av clone()-metoden – Deep Copy
- Hvis vi ønsker å lage en dyp kopi av objekt X og plassere den i et nytt objekt Y, opprettes en ny kopi av alle refererte objektfelter og disse referansene plasseres i objekt Y. Dette betyr eventuelle endringer i refererte objektfelt i objektet. X eller Y vil bare reflekteres i det objektet og ikke i det andre. I eksemplet nedenfor lager vi en dyp kopi av objektet.
- En dyp kopi kopierer alle feltene og lager kopier av dynamisk tildelt minne som feltene peker på. En dyp kopi oppstår når et objekt kopieres sammen med objektene det refererer til.
Java
// 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);> >}> }> |
>
>Produksjon
10 20 30 40 100 20 300 40>
I eksemplet ovenfor kan vi se at et nytt objekt for Test-klassen har blitt tildelt til å kopiere et objekt som vil bli returnert til klonemetoden. På grunn av dette vil t3 få en dyp kopi av objektet t1. Så eventuelle endringer som gjøres i 'c'-objektfeltene av t3, vil ikke bli reflektert i t1.
Deep Copy vs Shallow Copy
Det er visse forskjeller mellom å bruke clone() som en dyp kopi og den som en grunn kopi som nevnt nedenfor:
- Grunn kopi er metoden for å kopiere et objekt og følges som standard i kloning. I denne metoden kopieres feltene til et gammelt objekt X til det nye objektet Y. Mens objekttypefeltet kopieres, kopieres referansen til Y, dvs. objekt Y vil peke til samme plassering som påpekt av X. Hvis feltverdien er en primitiv type, den kopierer verdien til den primitive typen.
- Derfor vil alle endringer som gjøres i refererte objekter i objekt X eller Y reflekteres i andre objekter.
Grunne kopier er billige og enkle å lage. I eksemplet ovenfor laget vi en grunn kopi av de gjenstand.
Hvorfor bruke klonemetoden() eller Fordeler med klonemetoden
- Hvis vi bruker tilordningsoperatoren til å tilordne en objektreferanse til en annen referansevariabel, vil den peke til samme adresseplassering til det gamle objektet og ingen ny kopi av objektet vil bli opprettet. På grunn av dette vil eventuelle endringer i referansevariabelen reflekteres i det opprinnelige objektet.
- Hvis vi bruker en kopikonstruktør, må vi kopiere alle dataene eksplisitt, det vil si at vi må tilordne alle feltene til klassen i konstruktøren eksplisitt. Men i klonemetoden gjøres dette arbeidet med å lage en ny kopi av metoden selv. Så for å unngå ekstra behandling bruker vi objektkloning.