Java Object Cloning And The Difference Between Deep And Shallow Copy

Cloning

 
Clone is a Greek word meaning “branch.” It is nothing but the process of copying one object to produce the exact same object.
 
Cloning
 

What is the clone of an object in Java?

 
An object which is returned by the clone() method is known as a clone of an original instance. Clones are two separate objects in Java heap, having the same characteristics.
  
In Java, object cloning is of two types:
  1. Shallow Copy
  2. Deep Copy

Why Cloning?

 
clone() method is the fastest approach to copying an object. This process takes a fewer number of steps to accomplish.
 

How to Clone in java?

  1. By default, no Java class supports cloning but Java provides one interface called java.lang.Cloneable, a marker interface and by implementing this interface, we can make a duplicate copy of our object by calling clone() method of java.lang.Object class.
     
  2. clone() method is protected inside java.lang. Object class throws a java.lang.CloneNotSupportedException.
     
    Protected Object clone() throws a CloneNotSupportedException.
Note
  1. By default, clone() method gives a shallow copy of the object; i.e., if we invoke super.clone(), then it’s a shallow copy.
     
  2. If we want to have a deep copy, we have to override the clone() method and make it public by giving our own definition of making a copy of the object.
Example
  1. public class Employee implements Cloneable   
  2. {  
  3.     int id;  
  4.     String name;  
  5.   
  6.     public String toString()   
  7.     {  
  8.         return "id:- " + id + " name:- " + name;  
  9.     }  
  10.     static public void main(String sd[]) throws CloneNotSupportedException   
  11.     {  
  12.         Employee e1 = new Employee();  
  13.         e1.id = 101;  
  14.         e1.name = "Shweta";  
  15.   
  16.         Employee e2 = (Employee) e1.clone();  
  17.         System.out.println("Actual Object e1:- " + e1);  
  18.         System.out.println("Cloned Object e2:- " + e2);  
  19.         System.out.println("Actual object identity:- " + e1.hashCode());  
  20.         System.out.println("Cloned object identity:- " + e2.hashCode()); //both e1 and e2 object are separate objects inside heap  
  21.     }  
  22.   
  23. }  
Output 
 
Actual Object e1: id:- 101 name:- Shweta
Cloned Object e2: id:- 101 name:- Shweta
Actual object identity: 22068557
Cloned object identity: 29115481
 
Shallow Copy
 
Generally, clone() method of an object creates a new instance of the same class, and copies all the fields to the new instance and returns it. This is nothing but a shallow copy.
 
Object class provides a clone() method and provides support for the shallow copy. It returns ‘Object’ as a type and you need to explicitly cast back to your original object.
 
Note
If the original object has any references to other objects as fields, then only the references of those objects are copied into the clone object, a copy of those objects is not created.
 
Shallow Copy
 
Here, Employee e1 object has a reference of Address object a1, then Employee object e1 clone is created, but not of Address object a1.
  
Example
  1. Address.java
    1. public class Address   
    2. {  
    3.     public String city, state, country;  
    4.     public Address(String city, String state, String country)   
    5.     {  
    6.         this.city = city;  
    7.         this.state = state;  
    8.         this.country = country;  
    9.     }  
    10. }  
  2. Employee.java
    1. public class Employee implements Cloneable  
    2. {  
    3.     int id;  
    4.     String name;  
    5.     Address a1;  
    6.   
    7.     public Employee(int id, String name, Address a1)   
    8.     {  
    9.         this.id = id;  
    10.         this.name = name;  
    11.         this.a1 = a1;  
    12.     }  
    13.     public String toString()   
    14.     {  
    15.         return "id:- " + id + " ,name:- " + name + " ,city:- " + a1.city + " ,state:- " + a1.state + " ,country:- " + a1.country;  
    16.     }  
    17.     static public void main(String sd[]) throws CloneNotSupportedException   
    18.     {  
    19.         Address a1 = new Address("Ghaziabad""U.P.""INDIA");  
    20.         Employee e1 = new Employee(101"Shweta", a1);  
    21.   
    22.         Employee e2 = (Employee) e1.clone();  
    23.   
    24.         System.out.println("Actual Object:-\n" + e1);  
    25.         System.out.println("Cloned Object:- \n" + e2);  
    26.   
    27.         //Proof of same a1 object with both e1 and e2  
    28.         System.out.println("Actual Object with address object:-\n" + e1.a1.hashCode());  
    29.         System.out.println("Cloned Object with address object:- \n" + e2.a1.hashCode()); //both have same hashcode  
    30.     }  
    31.   
    32. }  
Output
 
Actual Object: id:- 101 ,name:- Shweta ,city:- Ghaziabad ,state:- U.P. ,country:- INDIA
Cloned Object: id:- 101 ,name:- Shweta ,city:- Ghaziabad ,state:- U.P. ,country:- INDIA
Actual Object with address object: 8152936
Cloned Object with address object: 8152936
 
Shallow Copy
 
 
Deep Copy
  
A deep copy of an object will have an exact copy of all the fields of the original object, just like the shallow copy. If the original object has any references to the other objects as fields, then a copy of those objects is also created by calling clone() method on them.
 
Note: To create a deep copy of an object, you must override the clone().
  
Example
  1. Address.java 
    1. public class Address implements Cloneable  
    2. {  
    3.     public String city, state, country;  
    4.     public Address(String city, String state, String country)  
    5.     {  
    6.         this.city = city;  
    7.         this.state = state;  
    8.         this.country = country;  
    9.     }  
    10.     protected Object clone() throws CloneNotSupportedException   
    11.     {  
    12.         return super.clone();  
    13.     }  
    14. }  
  2. Employee.java
    1. public class Employee implements Cloneable   
    2. {  
    3.     int id;  
    4.     String name;  
    5.     Address a1;  
    6.   
    7.     public Employee(int id, String name, Address a1)   
    8.     {  
    9.         this.id = id;  
    10.         this.name = name;  
    11.         this.a1 = a1;  
    12.     }  
    13.     public String toString()  
    14.     {  
    15.         return "id:- " + id + " ,name:- " + name + " ,city:- " + a1.city + " ,state:- " + a1.state + " ,country:- " + a1.country;  
    16.     }  
    17.   
    18.     public Object clone() throws CloneNotSupportedException  
    19.     {  
    20.         Employee e1 = (Employee) super.clone();  
    21.   
    22.         e1.a1 = (Address) a1.clone();  
    23.   
    24.         return e1;  
    25.     }  
    26.     static public void main(String sd[]) throws CloneNotSupportedException  
    27.     {  
    28.         Address a1 = new Address("Ghaziabad""U.P.""INDIA");  
    29.         Employee e1 = new Employee(101"Shweta", a1);  
    30.   
    31.         Employee e2 = (Employee) e1.clone();  
    32.   
    33.         System.out.println("Actual Object:-\n" + e1);  
    34.         System.out.println("Cloned Object:- \n" + e2);  
    35.   
    36.         //Proof of different Address object with e1 and e2  
    37.         System.out.println("Actual Object with address object:-\n" + e1.a1.hashCode());  
    38.         System.out.println("Cloned Object with address object:- \n" + e2.a1.hashCode()); //both have different hashcode  
    39.     }  
    40.   
    41. }  
Output
 
Actual Object: id:- 101 ,name:- Shweta ,city:- Ghaziabad ,state:- U.P. ,country:- INDIA
Cloned Object: id:- 101 ,name:- Shweta ,city:- Ghaziabad ,state:- U.P. ,country:- INDIA
Actual Object with address object: 23660326
Cloned Object with address object: 5538765
 
deep copy
 
Shallow Copy vs. Deep Copy in Java
 
Shallow Copy Deep Copy
Cloned object and original object are not 100% different. Cloned object and original object are 100% different
Shallow copy is preferred if an object has only primitive fields. Deep copy is preferred if an object has references to other objects as the fields.
Shallow copy is fast Deep copy is slow
No need to override clone(). Must have to override clone() method.