Le clonage d'objet fait référence à la création d'une copie exacte d'un objet. Il crée une nouvelle instance de la classe de l'objet courant et initialise tous ses champs avec exactement le contenu des champs correspondants de cet objet.
Méthodes pour effectuer le clonage d'objets en Java
Il existe 3 méthodes pour créer un clonage d'objets en Java, mentionnées ci-dessous :
- Utilisation de l'opérateur d'affectation pour créer une copie de la variable de référence
- Création d'une copie à l'aide de la méthode clone()
- Utilisation de la méthode clone() – Deep Copy
1. Utilisation de l'opérateur d'affectation pour créer un copie du variable de référence
En Java, il n'existe pas d'opérateur pour créer une copie d'un objet. Contrairement au C++, en Java, si nous utilisons l'opérateur d'affectation, cela créera une copie de la variable de référence et non de l'objet. Cela peut s’expliquer en prenant un exemple. Le programme suivant démontre la même chose.
Vous trouverez ci-dessous la mise en œuvre du sujet ci-dessus :
Java
chaîne 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);> >}> }> |
films
>
>Sortir
10 20 100 20 100 20>
2. Création d'une copie à l'aide de la méthode clone()
La classe dont la copie de l'objet doit être effectuée doit contenir une méthode de clonage publique ou dans l'une de ses classes parentes.
- Chaque classe qui implémente clone() doit appeler super.clone() pour obtenir la référence de l'objet cloné.
- La classe doit également implémenter l'interface java.lang.Cloneable dont nous voulons créer le clone d'objet, sinon elle lancera CloneNotSupportedException lorsque la méthode clone est appelée sur l'objet de cette classe.
Syntaxe:
protected Object clone() throws CloneNotSupportedException>
i) Utilisation de la méthode clone() -Shallow Copy
Note – Dans l'exemple de code ci-dessous, la méthode clone() crée un objet complètement nouvel avec une valeur hashCode différente, ce qui signifie qu'il se trouve dans un emplacement mémoire séparé. Mais comme l'objet Test c est à l'intérieur de Test2, les types primitifs ont réalisé une copie complète mais cet objet Test c est toujours partagé entre t1 et t2. Pour surmonter ce problème, nous effectuons explicitement une copie complète de la variable objet c, qui sera discutée plus tard.
afficher les applications cachées
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);> >}> }> |
flotter en chaîne
>
>Sortir
10 20 300 40 100 20 300 40>
Dans l'exemple ci-dessus, t1.clone renvoie la copie superficielle de l'objet t1. Pour obtenir une copie complète de l'objet, certaines modifications doivent être apportées à la méthode de clonage après l'obtention de la copie.
ii) Utilisation de la méthode clone() – Deep Copy
- Si nous voulons créer une copie complète de l'objet X et la placer dans un nouvel objet Y, une nouvelle copie de tous les champs d'objets référencés est créée et ces références sont placées dans l'objet Y. Cela signifie que toutes les modifications apportées aux champs d'objet référencés dans l'objet X ou Y sera reflété uniquement dans cet objet et pas dans l'autre. Dans l'exemple ci-dessous, nous créons une copie complète de l'objet.
- Une copie complète copie tous les champs et effectue des copies de la mémoire allouée dynamiquement et pointée par les champs. Une copie complète se produit lorsqu'un objet est copié avec les objets auxquels il fait référence.
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);> >}> }> |
>
modèles de logiciels Java
>Sortir
10 20 30 40 100 20 300 40>
Dans l'exemple ci-dessus, nous pouvons voir qu'un nouvel objet pour la classe Test a été assigné pour copier un objet qui sera renvoyé à la méthode clone. De ce fait, t3 obtiendra une copie complète de l’objet t1. Ainsi, toute modification apportée aux champs de l’objet « c » par t3 ne sera pas reflétée dans t1.
Copie approfondie vs copie superficielle
Il existe certaines différences entre l'utilisation de clone() comme copie complète et celle comme copie superficielle, comme mentionné ci-dessous :
- Copie superficielle est la méthode de copie d'un objet et est suivie par défaut lors du clonage. Dans cette méthode, les champs d'un ancien objet X sont copiés vers le nouvel objet Y. Lors de la copie du champ de type d'objet, la référence est copiée vers Y, c'est-à-dire que l'objet Y pointera vers le même emplacement que celui indiqué par X. Si la valeur du champ est un type primitif, il copie la valeur du type primitif.
- Par conséquent, toute modification apportée aux objets référencés dans l’objet X ou Y sera reflétée dans d’autres objets.
Les copies superficielles sont bon marché et simples à réaliser. Dans l'exemple ci-dessus, nous avons créé une copie superficielle de le objet.
Pourquoi utiliser la méthode clone() ou Avantages de la méthode Clone
- Si nous utilisons l'opérateur d'affectation pour attribuer une référence d'objet à une autre variable de référence, elle pointera vers le même emplacement d'adresse de l'ancien objet et aucune nouvelle copie de l'objet ne sera créée. De ce fait, toute modification apportée à la variable de référence sera reflétée dans l'objet d'origine.
- Si nous utilisons un constructeur de copie, nous devons alors copier explicitement toutes les données, c'est-à-dire que nous devons réaffecter explicitement tous les champs de la classe dans le constructeur. Mais dans la méthode clone, ce travail de création d’une nouvelle copie est effectué par la méthode elle-même. Donc, pour éviter un traitement supplémentaire, nous utilisons le clonage d'objets.