Klonování objektu znamená vytvoření přesné kopie objektu. Vytvoří novou instanci třídy aktuálního objektu a inicializuje všechna jeho pole přesně s obsahem odpovídajících polí tohoto objektu.
Metody pro provádění klonování objektů v Javě
Existují 3 způsoby vytváření klonování objektů v Javě, které jsou uvedeny níže:
- Pomocí operátoru přiřazení vytvořte kopii referenční proměnné
- Vytvoření kopie pomocí metody clone().
- Použití metody clone() – Deep Copy
1. Pomocí operátora přiřazení vytvořte a kopie referenční proměnná
V Javě neexistuje žádný operátor, který by vytvořil kopii objektu. Na rozdíl od C++ v Javě, pokud použijeme operátor přiřazení, vytvoří kopii referenční proměnné a ne objektu. To lze vysvětlit na příkladu. Následující program ukazuje totéž.
Níže je implementace výše uvedeného tématu:
Jáva
přepínač c#
// 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);> >}> }> |
>
>Výstup
10 20 100 20 100 20>
2. Vytvoření kopie pomocí metody clone().
Třída, jejíž kopie objektu má být vytvořena, musí mít v sobě nebo v jedné ze svých nadřazených tříd veřejnou metodu klonování.
ffilmy
- Každá třída, která implementuje clone(), by měla zavolat super.clone(), aby získala odkaz na klonovaný objekt.
- Třída musí také implementovat rozhraní java.lang.Cloneable, jehož klon objektu chceme vytvořit, jinak vyvolá CloneNotSupportedException, když je na objekt této třídy zavolána metoda klonování.
Syntax:
protected Object clone() throws CloneNotSupportedException>
i) Použití metody clone() -Shallow Copy
Poznámka – V níže uvedeném příkladu kódu metoda clone() vytváří zcela nový objekt s jinou hodnotou hashCode, což znamená, že je v samostatném paměťovém místě. Ale vzhledem k tomu, že objekt Test c je uvnitř Test2, primitivní typy dosáhly hluboké kopie, ale tento objekt Test c je stále sdílen mezi t1 a t2. Abychom to překonali, explicitně provedeme hlubokou kopii pro objektovou proměnnou c, o které bude řeč později.
Jáva
// 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);> >}> }> |
>
>Výstup
10 20 300 40 100 20 300 40>
Ve výše uvedeném příkladu t1.clone vrací mělkou kopii objektu t1. Chcete-li získat hlubokou kopii objektu, je třeba po získání kopie provést určité úpravy v metodě klonování.
ii) Použití metody clone() – Deep Copy
- Pokud chceme vytvořit hlubokou kopii objektu X a umístit ji do nového objektu Y, vytvoří se nová kopie všech polí odkazovaných objektů a tyto odkazy se umístí do objektu Y. To znamená, že jakékoli změny provedené v polích odkazovaných objektů v objektu X nebo Y se projeví pouze v tomto objektu a ne v druhém. V níže uvedeném příkladu vytvoříme hlubokou kopii objektu.
- Hluboká kopie zkopíruje všechna pole a vytvoří kopie dynamicky alokované paměti, na kterou pole ukazují. K hluboké kopii dochází, když je objekt zkopírován spolu s objekty, na které odkazuje.
Jáva
// 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);> >}> }> |
seznam polí seřazen
>
>Výstup
10 20 30 40 100 20 300 40>
Ve výše uvedeném příkladu můžeme vidět, že byl přiřazen nový objekt pro třídu Test pro kopírování objektu, který bude vrácen do metody clone. Díky tomu t3 získá hlubokou kopii objektu t1. Takže jakékoli změny provedené v polích objektu „c“ pomocí t3 se neprojeví v t1.
Deep Copy vs Shallow Copy
Existují určité rozdíly mezi použitím clone() jako hluboké kopie a použití jako mělké kopie, jak je uvedeno níže:
- Mělká kopie je metoda kopírování objektu a je standardně dodržována při klonování. Při této metodě se pole starého objektu X zkopírují do nového objektu Y. Při kopírování pole typu objektu se odkaz zkopíruje do Y, tj. objekt Y bude ukazovat na stejné místo, na které ukazuje X. Pokud hodnota pole je primitivní typ, kopíruje hodnotu primitivního typu.
- Jakékoli změny provedené v odkazovaných objektech v objektu X nebo Y se proto projeví v jiných objektech.
Mělké kopie jsou levné a snadno vyrobitelné. Ve výše uvedeném příkladu jsme vytvořili mělkou kopii a objekt.
Proč používat metodu clone() popř Výhody klonovací metody
- Pokud použijeme operátor přiřazení k přiřazení odkazu na objekt k jiné referenční proměnné, bude ukazovat na stejné umístění adresy starého objektu a nevytvoří se žádná nová kopie objektu. Díky tomu se jakékoli změny v referenční proměnné projeví v původním objektu.
- Pokud použijeme kopírovací konstruktor, pak musíme všechna data zkopírovat explicitně, tj. musíme explicitně přeřadit všechna pole třídy v konstruktoru. Ale v metodě klon je tato práce na vytvoření nové kopie prováděna samotnou metodou. Abychom se vyhnuli dalšímu zpracování, používáme klonování objektů.