Objektkloning hänvisar till skapandet av en exakt kopia av ett objekt. Den skapar en ny instans av klassen för det aktuella objektet och initierar alla dess fält med exakt innehållet i motsvarande fält för detta objekt.
Metoder för att utföra objektkloning i Java
Det finns tre metoder för att skapa objektkloning i Java som nämns nedan:
visa dolda appar
- Använda Assignment Operator för att skapa en kopia av referensvariabeln
- Skapa en kopia med metoden clone().
- Användning av metoden clone() – Deep Copy
1. Använda Assignment Operator för att skapa en kopia av referensvariabel
I Java finns det ingen operatör för att skapa en kopia av ett objekt. Till skillnad från C++, i Java, om vi använder tilldelningsoperatorn kommer den att skapa en kopia av referensvariabeln och inte objektet. Detta kan förklaras genom att ta ett exempel. Följande program visar detsamma.
Nedan är implementeringen av ovanstående ämne:
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);> >}> }> |
>
>Produktion
10 20 100 20 100 20>
2. Skapa en kopia med metoden clone()
Klassen vars objekts kopia ska göras måste ha en offentlig klonmetod i sig eller i en av dess överordnade klasser.
fmovies
- Varje klass som implementerar clone() bör anropa super.clone() för att erhålla den klonade objektreferensen.
- Klassen måste också implementera java.lang.Cloneable gränssnitt vars objektklon vi vill skapa, annars kommer den att kasta CloneNotSupportedException när klonmetoden anropas på den klassens objekt.
Syntax:
protected Object clone() throws CloneNotSupportedException>
i) Användning av metoden clone() -Shallow Copy
Notera – I kodexemplet nedan skapar metoden clone() ett helt nytt objekt med ett annat hashCode-värde, vilket betyder att det är på en separat minnesplats. Men på grund av att testobjektet c finns inuti Test2, har de primitiva typerna uppnått djup kopiering men detta testobjekt c delas fortfarande mellan t1 och t2. För att övervinna det gör vi uttryckligen en djupkopia för objektvariabel c, vilket diskuteras senare.
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);> >}> }> |
>
>Produktion
10 20 300 40 100 20 300 40>
I exemplet ovan returnerar t1.clone den ytliga kopian av objektet t1. För att få en djup kopia av objektet måste vissa modifieringar göras i klonmetoden efter att kopian erhållits.
ii) Användning av metoden clone() – Deep Copy
- Om vi vill skapa en djup kopia av objekt X och placera den i ett nytt objekt Y så skapas en ny kopia av eventuella refererade objektfält och dessa referenser placeras i objekt Y. Detta innebär alla ändringar som görs i refererade objektfält i objektet. X eller Y kommer endast att reflekteras i det objektet och inte i det andra. I exemplet nedan skapar vi en djup kopia av objektet.
- En djupkopia kopierar alla fält och gör kopior av dynamiskt allokerat minne som pekas på av fälten. En djupkopia uppstår när ett objekt kopieras tillsammans med de objekt som det refererar till.
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);> >}> }> |
arraylist sorterad
>
>Produktion
10 20 30 40 100 20 300 40>
I exemplet ovan kan vi se att ett nytt objekt för klassen Test har tilldelats att kopiera ett objekt som kommer att returneras till klonmetoden. På grund av detta kommer t3 att få en djup kopia av objektet t1. Så alla ändringar som görs i 'c'-objektfälten av t3, kommer inte att återspeglas i t1.
Deep Copy vs Shallow Copy
Det finns vissa skillnader mellan att använda clone() som en djup kopia och den som en ytlig kopia som nämns nedan:
- Grund kopia är metoden för att kopiera ett objekt och följs som standard vid kloning. I den här metoden kopieras fälten för ett gammalt objekt X till det nya objektet Y. När objekttypfältet kopieras kopieras referensen till Y, dvs objekt Y kommer att peka på samma plats som påpekats av X. Om fältvärdet är en primitiv typ, den kopierar värdet av den primitiva typen.
- Därför kommer alla ändringar som görs i refererade objekt i objekt X eller Y att återspeglas i andra objekt.
Grunda kopior är billiga och enkla att göra. I exemplet ovan skapade vi en ytlig kopia av de objekt.
Varför använda klonmetoden() eller Fördelar med klonmetoden
- Om vi använder tilldelningsoperatorn för att tilldela en objektreferens till en annan referensvariabel kommer den att peka på samma adressplats för det gamla objektet och ingen ny kopia av objektet kommer att skapas. På grund av detta kommer eventuella ändringar i referensvariabeln att återspeglas i det ursprungliga objektet.
- Om vi använder en kopieringskonstruktor måste vi kopiera all data explicit, dvs vi måste explicit omtilldela alla fält i klassen i konstruktorn. Men i klonmetoden görs detta arbete med att skapa en ny kopia av metoden själv. Så för att undvika extra bearbetning använder vi objektkloning.