Cloning in Java


Object class has a clone method which can be used to copy the values of an object without any side-effect in case instance variables are of primitive types. But in case of instance variables as objects, as only references are copied, side-effect plays its role. This problem can be solved by overriding the clone method. See the below example.

Example

Live Demo

public class Tester {
   public static void main(String[] args) throws CloneNotSupportedException {
      //Scenario 1: Shallow Copy
      B b1 = new B();
      A a1 = new A();
      a1.a = 1;
      a1.b = 2;

      b1.aObject = a1;
      b1.a = 1;
      //Print a1 object
      printObject(b1.aObject, "b1.a", b1.a);

      //clone operator copies the reference
      B b2 = b1.clone();

      //b1.aObject.a and b2.aObject.a are now pointing to same object
      //modify b2.aObject.a and changes will reflect in b1.aObject.a
      b2.aObject.a = 3;
      printObject(b1.aObject, "b1.a", b1.a);
      printObject(b2.aObject, "b2.a", b2.a);

      //Scenario 2: Using Deep Copy
      C c1 = new C();
      A a3 = new A();
      a3.a = 1;
      a3.b = 2;

      c1.aObject = a3;
      c1.a = 1;
      //Print a1 object
      printObject(c1.aObject, "c1.a", c1.a);

      C c2 = c1.clone();
      //c1.aObject.a and c2.aObject.a are now pointing to different object
      //modify c2.aObject.a and changes will not reflect in c1.aObject.a
      c2.aObject.a = 3;
      printObject(c1.aObject, "c1.a", c1.a);
      printObject(c2.aObject, "c2.a", c2.a);    
   }

   private static void printObject(A a, String name, int value) {
      System.out.println(name + ": [" + a.a + ", " + a.b + "]" + ", " + value);
   }
}

class A {
   public int a;
   public int b;
}

class B implements Cloneable {
   public int a;
   public A aObject;

   public B clone() throws CloneNotSupportedException {
      B b = (B)super.clone();
      return b;
   }
}

class C implements Cloneable {
   public int a;
   public A aObject;

   public C clone() throws CloneNotSupportedException {
      C c = (C)super.clone();
      c.aObject = new A();        
      c.aObject.a = this.aObject.a;
      c.aObject.b = this.aObject.b;
      return c;
   }
}

Output

b1.a: [1, 2], 1
b1.a: [3, 2], 1
b2.a: [3, 2], 1
c1.a: [1, 2], 1
c1.a: [1, 2], 1
c2.a: [3, 2], 1

Points to remember

  • clone() method has no side-effects in case of primitives instance variables, as a new object is created during cloning.

  • clone() method if not implemented properly, too has side-effects in case of objects as instance variables, as a cloned object to has a copy of references. This is termed as a shallow copy.

  • clone() method can be overridden to prevent shallow copy an instance variable objects can be separately created and their properties can be updated. This is termed as a deep copy.

Samual Sam
Samual Sam

Learning faster. Every day.

Updated on: 18-Jun-2020

170 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements