clone Method of Java Object Object Object

Keywords: Java

The purpose of cloning is to quickly create a copy of an existing object.

Cloning steps:

  1. Create an object
  2. Import the data of the original object into the newly created data

1. clone() source code of Object

  1. /** 
  2.  * Creates and returns a copy of this {@code Object}. The default 
  3.  * implementation returns a so-called "shallow" copy: It creates a new 
  4.  * instance of the same class and then copies the field values (including 
  5.  * object references) from this instance to the new instance. A "deep" copy, 
  6.  * in contrast, would also recursively clone nested objects. A subclass that 
  7.  * needs to implement this kind of cloning should call {@code super.clone()} 
  8.  * to create the new instance and then create deep copies of the nested, 
  9.  * mutable objects. 
  10.  * 
  11.  * @return a copy of this object. 
  12.  * @throws CloneNotSupportedException 
  13.  *             if this object's class does not implement the {@code 
  14.  *             Cloneable} interface. 
  15.  */  
  16. protected Object clone() throws CloneNotSupportedException {  
  17.     if (!(this instanceof Cloneable)) {  
  18.         throw new CloneNotSupportedException("Class doesn't implement Cloneable");  
  19.     }  
  20.   
  21.     return internalClone((Cloneable) this);  
  22. }  
  23.   
  24. /* 
  25.  * Native helper method for cloning. 
  26.  */  
  27. private native Object internalClone(Cloneable o);  

clone method first decides whether the object implements Cloneable interface, and if not throws CloneNotSupportedException. Finally, internalClone. intervalClone is called as a native method. Generally speaking, the execution efficiency of native method is higher than that of non-native method.

When a class overrides the clone method, it inherits the Cloneable interface. Usually cloned objects are cloned by super.clone() method.


2. Shallow clone

Cloning is copying a copy of an object. If only the field values of the object need to be copied (for basic data types, such as int,long,float, etc.), then the field values are copied; for composite data types, only the field values, such as array variables, copy the address; and for object variables, copy the reference of the object.

Example:

  1. public class ShadowClone implements Cloneable{  
  2.          
  3.     private int a;   //Basic types  
  4.     private int[] b; //Non-basic types  
  5.     //Rewrite the Object.clone() method and change protected to public  
  6.     @Override  
  7.     public Object clone(){  
  8.         ShadowClone sc = null;  
  9.         try  
  10.         {  
  11.             sc = (ShadowClone) super.clone();  
  12.         } catch (CloneNotSupportedException e){  
  13.             e.printStackTrace();  
  14.         }  
  15.         return sc;  
  16.     }  
  17.     public int getA()  
  18.     {  
  19.         return a;  
  20.     }  
  21.     public void setA(int a)  
  22.     {  
  23.         this.a = a;  
  24.     }  
  25.     public int[] getB() {  
  26.     return b;  
  27.     }  
  28.     public void setB(int[] b) {  
  29.     this.b = b;  
  30.     }    
  31. }  
Then test:

  1. public class Test{  
  2.     public static void main(String[] args) throws CloneNotSupportedException{  
  3.         ShadowClone c1 = new ShadowClone();  
  4.         //Assignment of c1  
  5.         c1.setA(100) ;  
  6.         c1.setB(new int[]{1000}) ;  
  7.           
  8.         System.out.println("Before cloning c1:  a="+c1.getA()+" b="+c1.getB()[0]);  
  9.         //Clone object c2 and modify attributes A, B and C of c2  
  10.         ShadowClone c2 = (ShadowClone) c1.clone();  
  11.         //Modification of c2  
  12.         c2.setA(50) ;  
  13.         int []a = c2.getB() ;  
  14.         a[0]=5 ;  
  15.         c2.setB(a);  
  16.         System.out.println("Before cloning c1:  a="+c1.getA()+" b="+c1.getB()[0]);  
  17.         System.out.println("After cloning c2:  a="+c2.getA()+ " b[0]="+c2.getB()[0]);  
  18.     }  
  19. }  
The result is:

Precloning c1: a=100 b=1000
Pre-cloning c1: a=100 b=5
Cloned c2: a=50 b[0]=5


Object models for c1 and c2:

                                                                     

As you can see, shallow cloning can be used for basic types, while for reference types, because the reference content is the same, changing the attributes in the c2 instance object will affect c1. So reference types need to use deep cloning. In addition, when developing an immutable class, if the members of the immutable class have reference types, deep cloning is needed to achieve the immutable purpose.

3. Deep clone

The difference between deep cloning and shallow cloning is the replication of composite data types. If a field in an object is of composite type, an object needs to be recreated for that field when cloning the object.

Example:

  1. public class DeepClone implements Cloneable {  
  2.   
  3.     private int a;   //Basic types  
  4.     private int[] b; //Non-basic types  
  5.     //Rewrite the Object.clone() method and change protected to public  
  6.     @Override  
  7.     public Object clone(){  
  8.         DeepClone sc = null;  
  9.         try  
  10.         {  
  11.             sc = (DeepClone) super.clone();  
  12.             int[] t = sc.getB();  
  13.             int[] b1 = new int[t.length];  
  14.             for (int i = 0; i < b1.length; i++) {  
  15.                 b1[i] = t[i];  
  16.             }  
  17.             sc.setB(b1);  
  18.         } catch (CloneNotSupportedException e){  
  19.             e.printStackTrace();  
  20.         }  
  21.         return sc;  
  22.     }  
  23.     public int getA()  
  24.     {  
  25.         return a;  
  26.     }  
  27.     public void setA(int a)  
  28.     {  
  29.         this.a = a;  
  30.     }  
  31.     public int[] getB() {  
  32.         return b;  
  33.     }  
  34.     public void setB(int[] b) {  
  35.         this.b = b;  
  36.     }  
  37. }  
  1.   

The result is:

Precloning c1: a=100 b=1000

Precloning c1: a=100 b=1000
Cloned c2: a=50 b[0]=5

Object Model:

                                        


4. Summary:

  1. Clone method is used to create copies of objects. In order to use clone method, classes must implement java.lang.Cloneable interface to override the protected method clone. If Clonebale interface is not implemented, CloneNotSupportedException will be thrown.
  2. Constructors are not called when cloning java objects
  3. java provides a default way to implement clone, called shallow copy, by creating a copy of an object and then copying the content by assigning values, which means that if your class contains reference types, then both the original object and the clone will point to the same reference content, which is dangerous because any change in a variable field will be reflected in the same reference they refer to. Let it be. In order to avoid this situation, it is necessary to clone the referenced content in depth.

Posted by jjjamie on Fri, 19 Apr 2019 19:42:34 -0700