logo

Clone()-methode in Java

Objectklonen verwijst naar het maken van een exacte kopie van een object. Het creëert een nieuwe instantie van de klasse van het huidige object en initialiseert al zijn velden met exact de inhoud van de overeenkomstige velden van dit object.

Methoden voor het klonen van objecten in Java

Er zijn 3 methoden voor het maken van objectklonen in Java, die hieronder worden vermeld:

  1. Gebruik de Assignment Operator om een ​​kopie van de referentievariabele te maken
  2. Een kopie maken met behulp van de clone()-methode
  3. Gebruik van de clone()-methode – Deep Copy

1. Gebruik de toewijzingsoperator om een kopie van de referentievariabele

In Java bestaat er geen operator die een kopie van een object kan maken. In tegenstelling tot C++ wordt er in Java, als we de toewijzingsoperator gebruiken, een kopie gemaakt van de referentievariabele en niet van het object. Dit kan worden verklaard aan de hand van een voorbeeld. Het volgende programma demonstreert hetzelfde.



Hieronder vindt u de implementatie van het bovenstaande onderwerp:

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);> >}> }>

arraylijst in Java

>

>

Uitvoer

10 20 100 20 100 20>

2. Een kopie maken met behulp van de clone()-methode

De klasse waarvan de kopie van het object moet worden gemaakt, moet een openbare kloonmethode bevatten of in een van de bovenliggende klassen.

ffilms
  • Elke klasse die clone() implementeert, moet super.clone() aanroepen om de gekloonde objectreferentie te verkrijgen.
  • De klasse moet ook de java.lang.Cloneable-interface implementeren waarvan we de objectkloon willen maken, anders wordt CloneNotSupportedException gegenereerd wanneer de kloonmethode wordt aangeroepen voor het object van die klasse.

Syntaxis:

protected Object clone() throws CloneNotSupportedException>

i) Gebruik van de clone()-methode -Shallow Copy

Opmerking – In het onderstaande codevoorbeeld creëert de clone()-methode een volledig nieuw object met een andere hashCode-waarde, wat betekent dat het zich op een aparte geheugenlocatie bevindt. Maar omdat het Testobject c zich in Test2 bevindt, hebben de primitieve typen een diepe kopie bereikt, maar dit Testobject c wordt nog steeds gedeeld tussen t1 en t2. Om dat te ondervangen doen we expliciet een diepe kopie voor objectvariabele c, die later wordt besproken.

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);> >}> }>

>

>

Uitvoer

10 20 300 40 100 20 300 40>

In het bovenstaande voorbeeld retourneert t1.clone de ondiepe kopie van het object t1. Om een ​​diepe kopie van het object te verkrijgen, moeten na het verkrijgen van de kopie bepaalde wijzigingen worden aangebracht in de kloonmethode.

ii) Gebruik van de clone()-methode – Deep Copy

  • Als we een diepe kopie van object X willen maken en deze in een nieuw object Y willen plaatsen, wordt er een nieuwe kopie van alle objectvelden waarnaar wordt verwezen gemaakt en worden deze verwijzingen in object Y geplaatst. Dit betekent dat alle wijzigingen die zijn aangebracht in objectvelden waarnaar wordt verwezen in het object X of Y wordt alleen in dat object weerspiegeld en niet in het andere. In het onderstaande voorbeeld maken we een diepe kopie van het object.
  • Een diepe kopie kopieert alle velden en maakt kopieën van het dynamisch toegewezen geheugen waarnaar de velden verwijzen. Er is sprake van een diepe kopie wanneer een object wordt gekopieerd samen met de objecten waarnaar het verwijst.

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);> >}> }>

diff in python

>

>

Uitvoer

10 20 30 40 100 20 300 40>

In het bovenstaande voorbeeld kunnen we zien dat een nieuw object voor de klasse Test is toegewezen om een ​​object te kopiëren dat wordt geretourneerd naar de kloonmethode. Hierdoor zal t3 een diepe kopie van het object t1 verkrijgen. Eventuele wijzigingen die door t3 in de ‘c’-objectvelden worden aangebracht, worden dus niet weerspiegeld in t1.

Diepe kopie versus ondiepe kopie

Er zijn bepaalde verschillen tussen het gebruik van clone() als een diepe kopie en dat als een ondiepe kopie, zoals hieronder vermeld:

  • Oppervlakkige kopie is de methode voor het kopiëren van een object en wordt standaard gevolgd bij het klonen. Bij deze methode worden de velden van een oud object X gekopieerd naar het nieuwe object Y. Tijdens het kopiëren van het objecttypeveld wordt de verwijzing gekopieerd naar Y, dat wil zeggen dat object Y naar dezelfde locatie verwijst als aangegeven door X. Als de veldwaarde is een primitief type, het kopieert de waarde van het primitieve type.
  • Daarom zullen alle wijzigingen die worden aangebracht in objecten waarnaar wordt verwezen in object X of Y, worden weerspiegeld in andere objecten.

Ondiepe kopieën zijn goedkoop en eenvoudig te maken. In het bovenstaande voorbeeld hebben we een ondiepe kopie gemaakt van de voorwerp.

Waarom de kloonmethode() of Voordelen van de kloonmethode

  • Als we de toewijzingsoperator gebruiken om een ​​objectreferentie aan een andere referentievariabele toe te wijzen, wijst deze naar dezelfde adreslocatie van het oude object en wordt er geen nieuwe kopie van het object gemaakt. Hierdoor worden eventuele wijzigingen in de referentievariabele weerspiegeld in het originele object.
  • Als we een kopieerconstructor gebruiken, moeten we alle gegevens expliciet kopiëren, dat wil zeggen dat we alle velden van de klasse in de constructor expliciet opnieuw moeten toewijzen. Maar bij de kloonmethode wordt het maken van een nieuwe kopie door de methode zelf gedaan. Om extra verwerking te voorkomen, gebruiken we objectklonen.