Object cloning refers to creation of shallow copy of an object.

Why we Need Clone?

// Java program to demonstrate that assignment
// operator only creates a new reference to same
// object.
import java.io.*;
 
// A test class whose objects are cloned
class Test
{
    int x, y;
    Test()
    {
        x = 10;
        y = 20;
    }
}
 
// Driver Class
class Main
{
    public static void main(String[] args)
    {
         Test ob1 = new Test();
 
         System.out.println(ob1.x + " " + ob1.y);
 
         // Creating a new reference variable ob2
         // pointing to same address as ob1
         Test ob2 = ob1;
 
         // Any change made in ob2 will be reflected
         // in ob1
         ob2.x = 100;
 
         System.out.println(ob1.x+" "+ob1.y);
         System.out.println(ob2.x+" "+ob2.y);
    }
}

output

10 20
100 20
100 20

In Java, we can create only copy of reference variable and not the object.

How to Use Clone?

  1. class that implements clone() should call super.clone() to obtain the cloned object reference
  2. the class must also implement java.lang.Cloneable interface whose object clone we want to create otherwise it will throw CloneNotSupportedException when clone method is called on that class’s object.
  3.   protected Object clone() throws CloneNotSupportedException
    
// A Java program to demonstrate shallow copy
// using clone()
import java.util.ArrayList;
 
// An object reference of this class is
// contained by Test2
class Test
{
    int x, y;
}
 
// Contains a reference of Test and implements
// clone with shallow copy.
class Test2 implements Cloneable
{
    int a;
    int b;
    Test c = new Test();
    public Object clone() throws
                   CloneNotSupportedException
    {
        return super.clone();
    }
}
 
// Driver class
public class Main
{
    public static void main(String args[]) throws
                          CloneNotSupportedException
    {
       Test2 t1 = new Test2();
       t1.a = 10;
       t1.b = 20;
       t1.c.x = 30;
       t1.c.y = 40;
 
       Test2 t2 = (Test2)t1.clone();
 
       // Creating a copy of object t1 and passing
       //  it to t2
       t2.a = 100;
 
       // Change in primitive type of t2 will not
       // be reflected in t1 field
       t2.c.x = 300;
 
       // Change in object type field will be
       // reflected in both t2 and t1(shallow copy)
       System.out.println(t1.a + " " + t1.b + " " +
                          t1.c.x + " " + t1.c.y);
       System.out.println(t2.a + " " + t2.b + " " +
                          t2.c.x + " " + t2.c.y);
    }
}

output

10 20 300 40
100 20 300 40

How to Achieve Deep Copy

// A Java program to demonstrate deep copy
// using clone()
import java.util.ArrayList;
 
// An object reference of this class is
// contained by Test2
class Test
{
    int x, y;
}
 
 
// Contains a reference of Test and implements
// clone with deep copy.
class Test2 implements Cloneable
{
    int a, b;
 
    Test c = new Test();
 
    public Object clone() throws
                CloneNotSupportedException
    {
        // Assign the shallow copy to new refernce variable t
        Test2 t = (Test2)super.clone();
 
        t.c = new Test();
 
        // Create a new object for the field c
        // and assign it to shallow copy obtained,
        // to make it a deep copy
        return t;
    }
}
 
public class Main
{
    public static void main(String args[]) throws
                             CloneNotSupportedException
    {
       Test2 t1 = new Test2();
       t1.a = 10;
       t1.b = 20;
       t1.c.x = 30;
       t1.c.y = 40;
 
       Test2 t3 = (Test2)t1.clone();
       t3.a = 100;
 
       // Change in primitive type of t2 will not
       // be reflected in t1 field
       t3.c.x = 300;
 
       // Change in object type field of t2 will not
       // be reflected in t1(deep copy)
       System.out.println(t1.a + " " + t1.b + " " +
                          t1.c.x + " " + t1.c.y);
       System.out.println(t3.a + " " + t3.b + " " +
                          t3.c.x + " " + t3.c.y);
    }
}

output

10 20 30 40
100 20 300 0

When to use Clone?

  1. We should use clone to copy arrays because that’s generally the fastest way to do it.

Disadvantages of Clone Method

  1. Cloneable interface lacks the clone() method. Actually, Cloneable is a marker interface and doesn’t have any methods in it, and we still need to implement it just to tell the JVM that we can perform clone() on our object.
  2. Object.clone() is protected, so we have to provide our own clone() and indirectly call Object.clone() from it.
  3. If we are writing a clone method in a child class, e.g. Person, then all of its superclasses should define the clone() method in them or inherit it from another parent class. Otherwise, the super.clone() chain will fail.
  4. We can not manipulate final fields in Object.clone() because final fields can only be changed through constructors. In our case, if we want every Person object to be unique by id, we will get the duplicate object if we use Object.clone() because Object.clone() will not call the constructor, and final id field can’t be modified from Person.clone().

There are two effective ways to create copy of object

  1. Copy Constructor – Refer here
  2. Serialization- Refer Here

Even copy constructor has its disadvantage since working with the internal object(Child Objects) may make it inconsistent and fragile

Comments are closed.