La clonació d'objectes es refereix a la creació d'una còpia exacta d'un objecte. Crea una nova instància de la classe de l'objecte actual i inicialitza tots els seus camps amb exactament el contingut dels camps corresponents d'aquest objecte.
Mètodes per realitzar la clonació d'objectes a Java
Hi ha 3 mètodes per crear la clonació d'objectes a Java que s'esmenten a continuació:
- Utilitzant l'operador d'assignació per crear una còpia de la variable de referència
- Creació d'una còpia mitjançant el mètode clone().
- Ús del mètode clone() - Còpia profunda
1. Utilitzant Assignment Operator per crear un còpia de la variable de referència
A Java, no hi ha cap operador per crear una còpia d'un objecte. A diferència de C++, a Java, si fem servir l'operador d'assignació, crearà una còpia de la variable de referència i no de l'objecte. Això es pot explicar prenent un exemple. El programa següent demostra el mateix.
A continuació es mostra la implementació del tema anterior:
Java
en cadena en 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);> >}> }> |
>
fmovies
>Sortida
10 20 100 20 100 20>
2. Creació d'una còpia mitjançant el mètode clone().
La classe de la qual s'ha de fer la còpia de l'objecte ha de tenir un mètode de clonació pública en ella o en una de les seves classes pare.
- Cada classe que implementi clone() hauria de cridar super.clone() per obtenir la referència de l'objecte clonat.
- La classe també ha d'implementar la interfície java.lang.Cloneable el clon d'objectes de la qual volem crear, en cas contrari, llançarà CloneNotSupportedException quan es crida al mètode de clonació a l'objecte d'aquesta classe.
Sintaxi:
protected Object clone() throws CloneNotSupportedException>
i) Ús del mètode clone() -Shallow Copy
Nota – A l'exemple de codi següent, el mètode clone() crea un objecte completament nou amb un valor hashCode diferent, el que significa que està en una ubicació de memòria independent. Però com que l'objecte de prova c està dins de Test2, els tipus primitius han aconseguit una còpia profunda, però aquest objecte de prova c encara es comparteix entre t1 i t2. Per superar-ho, fem explícitament una còpia profunda de la variable d'objecte c, que es comentarà més endavant.
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);> >}> }> |
>
>Sortida
10 20 300 40 100 20 300 40>
A l'exemple anterior, t1.clone retorna la còpia superficial de l'objecte t1. Per obtenir una còpia profunda de l'objecte s'han de fer determinades modificacions en el mètode de clonació després d'obtenir la còpia.
ii) Ús del mètode clone() – Còpia profunda
- Si volem crear una còpia profunda de l'objecte X i col·locar-lo en un nou objecte Y, es crearà una nova còpia dels camps d'objectes referenciats i aquestes referències es col·loquen a l'objecte Y. Això vol dir qualsevol canvi fet als camps d'objectes referenciats a l'objecte. X o Y es reflectiran només en aquest objecte i no en l'altre. A l'exemple següent, creem una còpia profunda de l'objecte.
- Una còpia profunda copia tots els camps i fa còpies de la memòria assignada dinàmicament apuntada pels camps. Una còpia profunda es produeix quan es copia un objecte juntament amb els objectes als quals fa referència.
Java
data mecanografiada
centos vs rhel
// 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);> >}> }> |
>
>Sortida
10 20 30 40 100 20 300 40>
A l'exemple anterior, podem veure que s'ha assignat un objecte nou per a la classe Test per copiar un objecte que es retornarà al mètode de clonació. A causa d'això, t3 obtindrà una còpia profunda de l'objecte t1. Per tant, qualsevol canvi fet als camps d'objecte 'c' per t3, no es reflectirà a t1.
Còpia profunda vs còpia superficial
Hi ha certes diferències entre utilitzar clone() com a còpia profunda i com a còpia superficial, com s'esmenta a continuació:
- Còpia poc profunda és el mètode per copiar un objecte i se segueix per defecte en la clonació. En aquest mètode, els camps d'un objecte antic X es copien al nou objecte Y. Mentre es copia el camp del tipus d'objecte, la referència es copia a Y, és a dir, l'objecte Y apuntarà a la mateixa ubicació que assenyala X. Si el valor del camp és un tipus primitiu, copia el valor del tipus primitiu.
- Per tant, qualsevol canvi fet als objectes referenciats a l'objecte X o Y es reflectirà en altres objectes.
Les còpies poc profundes són barates i senzilles de fer. A l'exemple anterior, hem creat una còpia superficial de el objecte.
Per què utilitzar el mètode clon() o Avantatges del Mètode Clon
- Si utilitzem l'operador d'assignació per assignar una referència d'objecte a una altra variable de referència, apuntarà a la mateixa ubicació de l'adreça de l'objecte antic i no es crearà cap còpia nova de l'objecte. A causa d'això, qualsevol canvi en la variable de referència es reflectirà a l'objecte original.
- Si fem servir un constructor de còpia, hem de copiar totes les dades de manera explícita, és a dir, hem de reassignar tots els camps de la classe al constructor de manera explícita. Però en el mètode de clonació, aquest treball de creació d'una còpia nova es fa pel mateix mètode. Així, per evitar un processament addicional, utilitzem la clonació d'objectes.