The Java.lang.Cloneable interface is a marker interface. It was introduced in JDK 1.0. There is a method clone() in the Object class. Cloneable interface is implemented by a class to make Object.clone() method valid thereby making field-for-field copy. This interface allows the implementing class to have its objects to be cloned instead of using a new operator.
Declaration
public interface Cloneable
Example 1: Below program explains that If you will try to Clone an object which doesn’t implement the Cloneable interface, it will CloneNotSupportedException, which you may want to handle.
Java
// Java program to Demonstrate the // application of Cloneable interface import java.io.*; import java.util.*; class Student { // attributes of Student class String name = null ; int id = 0 ; // default constructor Student() {} // parameterized constructor Student(String name, int id) { this .name = name; this .id = id; } public static void main(String[] args) { // create an instance of Student Student s1 = new Student( "Ashish" , 121 ); // Try to clone s1 and assign // the new object to s2 Student s2 = s1.clone(); } } |
Output:
prog.java:28: error: incompatible types: Object cannot be converted to Student Student s2 = s1.clone(); ^ 1 error
Example 2: Below code explains the proper usage of the Cloneable interface to make the Object.clone() method legal. Classes that implement this interface should override the Object.clone() method (which is protected) so that it can be invoked.
Java
// Java program to illustrate Cloneable interface import java.lang.Cloneable; // By implementing Cloneable interface // we make sure that instances of class A // can be cloned. class A implements Cloneable { int i; String s; // A class constructor public A( int i, String s) { this .i = i; this .s = s; } // Overriding clone() method // by simply calling Object class // clone() method. @Override protected Object clone() throws CloneNotSupportedException { return super .clone(); } } public class Test { public static void main(String[] args) throws CloneNotSupportedException { A a = new A( 20 , "GeeksForGeeks" ); // cloning 'a' and holding // new cloned object reference in b // down-casting as clone() return type is Object A b = (A)a.clone(); System.out.println(b.i); System.out.println(b.s); } } |
20 GeeksForGeeks
Deep Copy using clone() method
Deep Object Cloning is like creating an exact copy of the original object by copying the fields from the original object to the cloned object. A separate memory is allocated for the cloned objects where the original object content is copied. clone() method can create both shallow and deep copy of the original object based on the implementation of it. Deep copy creates a new memory with the contents same as the original object. That’s why when we change the content of the original object after cloning, the changes do not reflect in the clone object. There are types of copies such as Deep, Shallow, and Lazy Copy. The below code explains the deep copy using the clone() method.
Java
// 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 reference 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); } } |
10 20 30 40 100 20 300 0
Note: This interface does not contain the clone method. Therefore, it is not possible to clone an object merely by virtue of the fact that it implements this interface. Even if the clone method is invoked reflectively, there is no guarantee that it will succeed.
Reference: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Cloneable.html