Klonowanie obiektów odnosi się do tworzenia dokładnej kopii obiektu. Tworzy nową instancję klasy bieżącego obiektu i inicjuje wszystkie jej pola dokładnie zawartością odpowiednich pól tego obiektu.
Metody wykonywania klonowania obiektów w Javie
Istnieją 3 metody tworzenia klonowania obiektów w Javie, które wymieniono poniżej:
- Użycie operatora przypisania do utworzenia kopii zmiennej referencyjnej
- Tworzenie kopii za pomocą metody clone().
- Zastosowanie metody clone() – Deep Copy
1. Używanie operatora przypisania do tworzenia kopia zmienna referencyjna
W Javie nie ma operatora umożliwiającego utworzenie kopii obiektu. W przeciwieństwie do C++, w Javie, jeśli użyjemy operatora przypisania, utworzy on kopię zmiennej referencyjnej, a nie obiektu. Można to wyjaśnić na przykładzie. Poniższy program demonstruje to samo.
Poniżej realizacja powyższego tematu:
Jawa
Słownik 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);> >}> }> |
filmy
>
>Wyjście
10 20 100 20 100 20>
2. Tworzenie kopii za pomocą metody clone().
Klasa, której obiekt ma zostać wykonana kopia, musi posiadać w sobie lub w jednej z klas nadrzędnych metodę publicznego klonowania.
- Każda klasa implementująca clone() powinna wywołać super.clone() w celu uzyskania odwołania do sklonowanego obiektu.
- Klasa musi także implementować interfejs java.lang.Cloneable, którego klon obiektu chcemy utworzyć, w przeciwnym razie zgłosi wyjątek CloneNotSupportedException, gdy na obiekcie tej klasy zostanie wywołana metoda klonowania.
Składnia:
protected Object clone() throws CloneNotSupportedException>
i) Użycie metody clone() - Płytka kopia
Notatka – W poniższym przykładzie kodu metoda clone() tworzy zupełnie nowy obiekt z inną wartością hashCode, co oznacza, że znajduje się on w osobnej lokalizacji w pamięci. Ponieważ jednak obiekt testowy c znajduje się w teście2, typy pierwotne osiągnęły głęboką kopię, ale ten obiekt testowy c jest nadal współdzielony między t1 i t2. Aby temu zaradzić, jawnie wykonujemy głęboką kopię zmiennej obiektowej c, co zostanie omówione później.
blokuj reklamy YouTube na Androidzie
Jawa
// 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);> >}> }> |
if else instrukcje Java
>
>Wyjście
10 20 300 40 100 20 300 40>
W powyższym przykładzie t1.clone zwraca płytką kopię obiektu t1. Aby uzyskać głęboką kopię obiektu, po uzyskaniu kopii należy dokonać pewnych modyfikacji w metodzie klonowania.
ii) Zastosowanie metody clone() – Deep Copy
- Jeśli chcemy utworzyć głęboką kopię obiektu X i umieścić ją w nowym obiekcie Y, wówczas tworzona jest nowa kopia wszelkich pól obiektów, do których istnieją odniesienia, a odniesienia te umieszczane są w obiekcie Y. Oznacza to wszelkie zmiany dokonane w polach obiektów, do których istnieją odniesienia w obiekcie X lub Y zostaną odzwierciedlone tylko w tym obiekcie, a nie w drugim. W poniższym przykładzie tworzymy głęboką kopię obiektu.
- Głęboka kopia kopiuje wszystkie pola i tworzy kopie dynamicznie alokowanej pamięci, na którą wskazują pola. Głęboka kopia ma miejsce, gdy obiekt jest kopiowany wraz z obiektami, do których się odnosi.
Jawa
// 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);> >}> }> |
>
1 z 1000
>Wyjście
10 20 30 40 100 20 300 40>
W powyższym przykładzie widzimy, że do klasy Test został przypisany nowy obiekt w celu skopiowania obiektu, który zostanie zwrócony do metody clone. Dzięki temu t3 uzyska głęboką kopię obiektu t1. Zatem wszelkie zmiany wprowadzone w polach obiektu „c” do czasu t3 nie zostaną odzwierciedlone w t1.
Głęboka kopia kontra płytka kopia
Istnieją pewne różnice między używaniem funkcji clone() jako głębokiej kopii a płytkiej kopii, jak wspomniano poniżej:
- Płytka kopia to metoda kopiowania obiektu, stosowana domyślnie podczas klonowania. W tej metodzie pola starego obiektu X są kopiowane do nowego obiektu Y. Podczas kopiowania pola typu obiektu odwołanie jest kopiowane do Y, czyli obiekt Y będzie wskazywał to samo miejsce, które wskazał X. Jeżeli wartość pola jest typem pierwotnym, kopiuje wartość typu pierwotnego.
- Dlatego wszelkie zmiany dokonane w obiektach odniesienia w obiekcie X lub Y zostaną odzwierciedlone w innych obiektach.
Płytkie kopie są tanie i proste w wykonaniu. W powyższym przykładzie utworzyliśmy płytką kopię the obiekt.
Po co używać metody klonowania() lub Zalety metody klonowania
- Jeśli użyjemy operatora przypisania do przypisania odniesienia do obiektu do innej zmiennej odniesienia, wówczas wskaże on tę samą lokalizację adresową starego obiektu i nie zostanie utworzona żadna nowa kopia obiektu. Dzięki temu wszelkie zmiany w zmiennej referencyjnej zostaną odzwierciedlone w oryginalnym obiekcie.
- Jeśli użyjemy konstruktora kopiującego, musimy jawnie skopiować wszystkie dane, tj. musimy jawnie ponownie przypisać wszystkie pola klasy w konstruktorze. Ale w metodzie klonowania praca polegająca na utworzeniu nowej kopii jest wykonywana przez samą metodę. Aby uniknąć dodatkowego przetwarzania, używamy klonowania obiektów.