Shallow copy of Java prototype pattern-deep copy

Source: Internet
Author: User

First, what is it?

Shallow copy : Copy the value of a member variable of a value type , copy only the reference to a member variable of the reference type, and do not copy the referenced object

deep copy: a copy of a value for a member variable of a value type , and a reference object for a member variable of a reference type

internal mechanism:

(1) clone method for Object class

The default implementation is shallow copy, overriding the Clone method in the object class. The parent class of all classes in Java is the object class, and there is a clone method in the object class that returns a copy of the object, but its scope is protected type, and the generic class cannot be called. Therefore, the prototype class needs to modify the scope of the Clone method to the public type.

(2) about Java.lang.Cloneable interface

in the Java language, there is a cloneable interface, which only works by notifying the virtual machine at runtime that it can safely use the Clone method on classes that implement this interface. In a Java virtual machine, only classes that implement this interface can be copied, or clonenotsupportedexception exceptions will be thrown at run time.

Second, how to use? (i) Shallow copy

Shallow copy application: If you change a very basic type of value, the original object's value does not require a change when the shallow copy. is always in the state of coverage. For example:

Packagelc.clone.shadow;public Classshadowclone implements cloneable{//basic type private int A;    Non-basic type private String B;    Non-basic type private int[] C;        Override the Object.clone () method and change the protected to public @Override public Object clone () {Shadowclone sc = null;        try {sc = (Shadowclone) super.clone ();        } catch (Clonenotsupportedexception e) {e.printstacktrace ();    } return SC;    } public int Geta () {return A;    } public void SetA (int a) {this.a = A;    } public String Getb () {return b;    The public void Setb (String b) {this.b = b;    } public int[] GetC () {return C;    } public void SetC (int[] c) {this.c = C; }} Test class Test.java Packagelc.clone.shadow;public class test{public static void Main (string[] args) throws Clonenotsupport        edexception {Shadowclone C1 = new Shadowclone (); Assign a value to C1 C1.seta (100) ;        C1.SETB ("Clone1");               C1.SETC (New int[]{1000});        System.out.println ("Pre-clone: C1.a=" +c1.geta ());        System.out.println ("Pre-clone: C1.b=" +c1.getb ());       System.out.println ("Pre-clone: C1.c[0]=" +c1.getc () [0]);               System.out.println ("-----------");               Clones the object C2 and modifies the C2 property a,b,c shadowclone c2 = (shadowclone) c1.clone ();        Modify the C2 C2.seta (50);        C2.SETB ("Clone2");        int []a = C2.getc ();        a[0]=500;               C2.setc (a);        System.out.println ("After cloning: C1.a=" +c1.geta ());        System.out.println ("After cloning: c1.b=" +C1.GETB ());       System.out.println ("After cloning: c1.c[0]=" +c1.getc () [0]);               System.out.println ("---------------");        System.out.println ("After cloning: c2.a=" + C2.geta ());        System.out.println ("After cloning: c2.b=" + C2.GETB ());    System.out.println ("After cloning: c2.c[0]=" + c2.getc () [0]); }} results: Before cloning: C1.a=100 clone before: C1.b=clone1 clone: c1.c[0]=1000-----------clone: After c1.a=100 clone: C1.b=clone1 clone: C1.c[0]=500---------------after cloning: c2.a=50 after cloning: C2.b=clone2 after cloning: c2.c[0]=500 
<span style= "FONT-SIZE:14PT; Font-family:simsun; Background-color:rgb (255, 255, 255); " > </span>

there's a problem. , I mean modified the value of the cloned object c2.c, but the value of c1.c also changed, equal to the value of C2. The following conclusions are drawn for light cloning : The base type can be cloned, but the reference type is just the copy address, and there is no copy of the value of the object that the address points to, which makes two addresses point to the same value, modifies one, and of course the other changes. .

This shows , shallow clones are only suitable for cloning basic types and cannot be cloned for reference types .

(ii) deep copy

Using serialization for deep copy :

The process of writing an object into a stream is a serialization (serialization) process, while the process of reading an object from the stream is called a deserialization (deserialization) process. It should be noted that a copy of the object is written to the stream, and the original object still exists inside the JVM.

  in the Java language, the deep cloning of an object, it is often possible to enable the object to implement the Serializable interface, and then the object (actually a copy of the object) is written into a stream (serialized), and then read back from the stream (deserialization), The object can be rebuilt.

Object being cloned . Deepclone.java

Packagelc.clone.deep;importjava.io.serializable;<span style= "color: #cc0000;"    >//to implement a deep clone must implement the Serializable interface </span>public Classdeepclone implements serializable{private int A;    Private String B;    Private int[] C;    public int Geta () {return A;    } public void SetA (int a) {this.a = A;    } public String Getb () {return b;    The public void Setb (String b) {this.b = b;    } public int[] GetC () {return C;    } public void SetC (int[] c) {this.c = C; }} Test class Test.java Packagelc.clone.deep;importjava.io.bytearrayinputstream;importjava.io.bytearrayoutputstream;    Importjava.io.ioexception;importjava.io.objectinputstream;importjava.io.objectoutputstream;public class Test{        public static void Main (string[] args) throws clonenotsupportedexception {Test T = new Test ();        Deepclone DC1 = new Deepclone ();        to DC1 Assignment Dc1.seta (100);        DC1.SETB ("Clone1"); DC1.SETC (New INt[] {1000});        System.out.println ("Pre-clone: Dc1.a=" + Dc1.geta ());        System.out.println ("Pre-clone: dc1.b=" + DC1.GETB ());       System.out.println ("Pre-clone: dc1.c[0]=" + dc1.getc () [0]);        System.out.println ("-----------");        Deepclone DC2 = (deepclone) t.deepclone (DC1);        Modify the C2 Dc2.seta (50);        DC2.SETB ("Clone2");        Int[] A = DC2.GETC ();        A[0] = 500;        Dc2.setc (a);        System.out.println ("Pre-clone: Dc1.a=" + Dc1.geta ());        System.out.println ("Pre-clone: dc1.b=" + DC1.GETB ());       System.out.println ("Pre-clone: dc1.c[0]=" + dc1.getc () [0]);        System.out.println ("-----------");        System.out.println ("After cloning: dc2.a=" + Dc2.geta ());        System.out.println ("After cloning: dc2.b=" + DC2.GETB ());    System.out.println ("After cloning: dc2.c[0]=" + dc2.getc () [0]); } <span style= "color: #cc0000;"        >//using serialization and deserialization to implement a deep clone </span> public object Deepclone (object src) {object o = null;  try {if (src! = null) {  <span style= "color: #cc0000;"                >//writes the object into the stream </span> bytearrayoutputstream BAOs =new bytearrayoutputstream ();                ObjectOutputStream Oos = Newobjectoutputstream (BAOs);                Oos.writeobject (SRC);   Oos.close (); <span style= "color: #cc0000;"                        >//Read the object out of the stream </span> bytearrayinputstream Bais = Newbytearrayinputstream (BAOs                . Tobytearray ());                ObjectInputStream ois = Newobjectinputstream (Bais);                o = Ois.readobject ();            Ois.close ();        }} catch (IOException e) {e.printstacktrace ();        } catch (ClassNotFoundException e) {e.printstacktrace ();    } return o; }} results: Before cloning: Dc1.a=100 clone before: Dc1.b=clone1 clone before: dc1.c[0]=1000-----------clone: dc1.a=100 before cloning: Dc1.b=clone1 before cloning: dc1.c[0]=1000-- ---------after cloning: dc2.a=50 after cloning: Dc2.b=clone2 after cloning: Dc2.c[0]=500<span style= "FONT-SIZE:14PT; Font-family:simsun; BAckground-color:rgb (255, 255, 255); " > </span>

after deep cloning : modify DC1 or DC2, whether they are basic or reference types, their values will not change as one party changes the other .

The premise of this is that objects and all objects referenced inside the object are serializable, otherwise, it is necessary to carefully examine whether those objects that are not serializable can be set to transient, thus excluding them from the replication process.

a shallow copy is obviously easier to implement than a deep copy because all classes in the Java language inherit a clone () method, and the Clone () method does a formal shallow Copy .

There are some objects, such as threads (Thread) object or socket object, is not simple to copy or share. Whether using a shallow copy or a deep copy , as long as the indirect object is involved, the indirect object must be set to transient and not copied, or the program creates a fairly homogeneous object by itself. Right vote is used as a copy piece.

Third, contrast

through the above brief introduction to the shallow copy and deep copy, estimated in the brain already understood the approximate, then through the contrast to completely eliminate the doubt to them!


By contrast, you can see the essence: A shallow copy points to the same reference object, while a deep copy points to two completely different reference objects. So if you don't want the reference object to change, you have to use a deep copy. If it is simply a value type then both can be, then practice in future projects!

Iv. Summary

In summary, whether it is a shallow copy or a deep copy as long as the problem is a good copy, so in the future practice to understand their value, and let each value to maximize.


Shallow copy of Java prototype pattern-deep copy

Related Article

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.