"Shadow Clones" and "Deep clones" of Java

Source: Internet
Author: User

Today to learn the cloning of Java objects, in writing code, sometimes we write: Object 1 = Object 2, that is, Object 2 is assigned to object 1, but there is a problem, if we modify the property value of Object 2, the same property value of object 1 has been modified, and vice versa, Let me prove it:

 Public class A {    private  String msg;      Public A () {        = "Hello";    }      Public String getmsg () {        return  msg;    }      Public void setmsg (String msg) {        this. msg = msg;    }} 
 Public class Main {    publicstaticvoid  main (string[] args) {        new A ();         New A ();        System.out.println ("a1.msg:" + a1.getmsg ());         = A2;        A2.setmsg ("World");        System.out.println ("a1.msg:" + a1.getmsg ());}    }

Operation Result:

As can be seen from the main class, at first we new two objects, that is, the JVM heap memory opened up two memory space, and then assign the A2 to A1, which means that A2 and A1 objects point to the same reference in the stack memory, this time we modify the A2 object properties, A1 object properties will also change , in turn, for example, I'm now modifying the properties of A1 to try to see if the properties of A2 have been changed:

 Public class Main {    publicstaticvoid  main (string[] args) {        new A ();         New A ();        System.out.println ("a1.msg:" + a1.getmsg ());         = A2;        A1.setmsg ("Java");        System.out.println ("a2.msg:" + a2.getmsg ());}    }

No suspense changes, that is, the use of the "=" operator will be two objects to the same reference, two objects of the property values are interoperable, one object changes will necessarily be synchronized to another object, but sometimes we do not want to change one object to cause the change of another object, We want the A2 object to be created with the initial value of the A1 object, but the change of the A2 object property will not affect the A1 object, so we should use the object's clone, the clone of the object and the shallow clone and deep clone, we first look at the implementation of the shallow clone:

 Public classAImplementscloneable {PrivateString msg;  PublicA () {msg= "Hello"; }     PublicString getmsg () {returnmsg; }     Public voidsetmsg (String msg) { This. msg =msg; } @OverrideprotectedObject Clone ()throwsclonenotsupportedexception {return Super. Clone (); }}
 public  class   Main { static  void  main (string[] args) throws   clonenotsupportedexception {A a1  = new<        /span> A ();        System.out.println ( "a1.msg:" + a1.getmsg ());        A A2  = (a) a1.clone ();        System.out.println ( "a2.msg:" + a2.getmsg ());        A2.setmsg ( "Java" );        System.out.println ( "a1.msg:" + a1.getmsg ());    System.out.println ( "a2.msg:" + a2.getmsg ()); }}

You can see that the cloning of the implementation of the object is relatively simple, first of all, the class should implement the Cloneable interface and overwrite the Clone method of the object root class, note that cloneable is just a markup interface, there is no method defined in the Clone method, the implementation is very simple, It would be nice to call the Clone method of the parent class object. Now look at the main class and know that the MSG initialization of the A2 object is "Hello", and the value of the MSG attribute of the A2 is changed to "Java" without affecting the MSG value of the A1 object, whose value is still "Hello". We just saw a shallow clone, no set properties, if there are set properties, shallow cloning can not cope with this situation, we look at the code:

 Public classAImplementscloneable {PrivateList<string>list;  PublicA () {list=NewArraylist<string>(); List.add ("Hello"); List.add ("World"); }         PublicList<string>getList () {returnlist; }     Public voidSetlist (list<string>list) {         This. List =list; } @OverrideprotectedObject Clone ()throwsclonenotsupportedexception {return Super. Clone (); }}
 Public classMain { Public Static voidMain (string[] args)throwsclonenotsupportedexception {A A1=NewA (); System.out.println ("A1.list:" +a1.getlist ()); A A2=(A) A1.clone (); System.out.println ("A2.list:" +a2.getlist ()); A2.getlist (). Add ("Java"); System.out.println ("A1.list:" +a1.getlist ()); System.out.println ("A2.list:" +a2.getlist ()); }}

Let's see, the Magic Spell has appeared again, even though we have implemented the object's cloning, but because the object's properties are collection classes, so we modify the value in the collection class of the A2 object, it will also affect the value of the A1 object collection class, because the A1 and A2 object's List property points to the same memory address, In the face of this situation, we need to use the deep clone of the object, how to implement it, to see the code:

 Public classAImplementscloneable {PrivateList<string>list;  PublicA () {list=NewArraylist<string>(); List.add ("Hello"); List.add ("World"); }         PublicList<string>getList () {returnlist; }     Public voidSetlist (list<string>list) {         This. List =list; } @OverrideprotectedA Clone ()throwsclonenotsupportedexception {A other= (A)Super. Clone (); List<String> otherlist =NewArraylist<string>();  for(String s:list) {Otherlist.add (s);        } other.setlist (Otherlist); returnOther ; }}
 Public classMain { Public Static voidMain (string[] args)throwsclonenotsupportedexception {A A1=NewA (); System.out.println ("A1.list:" +a1.getlist ()); A A2=(A) A1.clone (); System.out.println ("A2.list:" +a2.getlist ()); A2.getlist (). Add ("Java"); System.out.println ("A1.list:" +a1.getlist ()); System.out.println ("A2.list:" +a2.getlist ()); }}

As you can see, the implementation of the deep clone is to make a new list in the Clone method, and assign the value of the original object list to the list and set the new list to the new object. So a2.list worth the change will not affect the a1.list, think if the original class property is an object, and the object's properties have objects and collection classes, then the Clone method inside the code will be very large, because deep cloning must ensure full cloning.

Shadow clones and deep clones of Java

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.