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?
- class that implements clone() should call super.clone() to obtain the cloned object reference
- 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.
-
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?
- We should use clone to copy arrays because that’s generally the fastest way to do it.
Disadvantages of Clone Method
- 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.
- Object.clone() is protected, so we have to provide our own clone() and indirectly call Object.clone() from it.
- 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.
- 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
Even copy constructor has its disadvantage since working with the internal object(Child Objects) may make it inconsistent and fragile