Edit Page

Cloning: Shallow Cloning and Deep Cloning

Introduction

Cloning is the process of creating an exact copy of an existing object with its values into a new object. Before we discuss the concept of cloning, we need to understand Java’s data types and how the Java memory model works. Please refer to lecture notes on Memory Management: Stack and Heap. Clones of an object can be made as either a shallow copy or a deep copy.

Sine JDK version 1, Java has an interface called Cloneable ↗, which is a marker interface. Any class that implements this interface will have to override the clone method to make a field-for-field copy of the object itself. The Object class, which is the root of the class hierarchy, does not implement this interface bit it does have a specific method called Object.clone() but overriding this method requires that the class of this object to implement the Cloneable interface to indicate that instances can be cloned. If the Cloneable interface is not implemented and you attempt to call the Object’s clone method, then a CloneNotSupportedException is thrown. The default implementation of the Object’s clone() method creates a shallow copy of an object. To create the deep copy of an object, you have to override the clone() method. In this lecture note, we will take a look at how to make a clone of an object as both a shallow copy and a deep copy.

Shallow Copy

This is also known as a field-by-field copy. A shallow copy of an object will have the exact copy of all the fields of the original object along with its references. Any changes made to references to objects by the cloned object will be also reflected in original object or vice-versa. A shallow copy is not 100% independent of the original object.

In Java, the default implementation of Object.clone() is a shallow copy. If you need a deep copy of an object, you must implement that in the class’ clone() method.

Example: Consider the following Java classes:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
public class Subject{
  private String name;
  private String code;
  
  public Subject(String name, String code){
    this.name = name;
    this.code = code;
  }
  public String getName(){return this.name;}
  public void setName(String name){this.name = name;}
  public String getCode(){return this.code;}
  public void setCode(String code){this.code = code;}

  @Override
  public String toString(){
    return this.name + " (" + this.code + ")";
  }
}

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Course implements Cloneable{
  private String name;
  private int number;
  private Subject subject;

  public Course(String name, int number, Subject subject){
    this.name = name;
    this.number = number;
    this.subject = subject;
  }
  public String getName(){return this.name;}
  public void setName(String name){this.name = name;}
  public int getNumber(){return this.number;}
  public void setNumber(int number){this.number = number;}
  public Subject getSubject(){return this.subject;}
  public void setSubject(Subject subject){this.subject = subject;}

  @Override
  public Course clone(){
    return new Course(this.name, this.number, this.subject);
  }

  @Override
  public String toString(){
    return this.name + " " + this.number + " " + this.subject;
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
public class ShallowCopyDemo {
  public static void main(String[] args) {
    Subject s1 = new Subject("Biology", "BIO");
    Course c1 = new Course("Intro to Biology", 101, s1);
    Course c2 = c1.clone();

    c2.getSubject().setName("Physics");
    c2.getSubject().setCode("PHY");
    c2.setName("Intro to Physics");
    
    System.out.println(c1);
    System.out.println(c2);
  }
}

Running the program results in the changes to the inner object (Subject) being reflected in both instances of the Course object.

Intro to Biology 101 Physics (PHY)
Intro to Physics 101 Physics (PHY)

running the program results in the changes to the inner object (Subject) reflected in both instances of the Course object.

Deep Copy

A deep copy of an object will have the exact copy of all the fields of the original object. If the original object has additional references to other objects, then copy of those objects will be created. Any changes made to references to objects by the cloned object will not be reflected in original object or vice-versa. A deep copy is 100% independent of the original object.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Course implements Cloneable{
  private String name;
  private int number;
  private Subject subject;

  public Course(String name, int number, Subject subject){
    this.name = name;
    this.number = number;
    this.subject = subject;
  }
  public String getName(){return this.name;}
  public void setName(String name){this.name = name;}
  public int getNumber(){return this.number;}
  public void setNumber(int number){this.number = number;}
  public Subject getSubject(){return this.subject;}
  public void setSubject(Subject subject){this.subject = subject;}

  @Override
  public Course clone(){
    return new Course(this.name, this.number, new Subject(this.subject.getName(), this.subject.getCode()));
  }

  @Override
  public String toString(){
    return this.name + " " + this.number + " " + this.subject;
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
public class DeepCopyDemo {
  public static void main(String[] args) {
    Subject s1 = new Subject("Biology", "BIO");
    Course c1 = new Course("Intro to Biology", 101, s1);
    Course c2 = c1.clone();

    c2.getSubject().setName("Physics");
    c2.getSubject().setCode("PHY");
    c2.setName("Intro to Physics");
    
    System.out.println(c1);
    System.out.println(c2);
  }
}

Running the program results in the changes to the inner object (Subject) being not reflected in the original instance of the Course object.

Intro to Biology 101 Biology (BIO)
Intro to Physics 101 Physics (PHY)

Running the program results in the changes to the inner object (Subject) being ** not ** reflected in the original instance of the Course object.

Summary

Shallow CopyDeep Copy
Cloned Object and original object are not 100% independent.Cloned Object and original object are 100% independent.
Any changes made to the cloned object will also be reflected in the original object or vice versa.Any changes made to cloned object will not be reflected in the original object or vice versa.
Shallow copy is fast and also less expensive. .Deep copy is slow and more expensive