In general, cloning defines as making an identical copy of something. In programming languages, cloning can be applied at different occasion and can provide various benefits. Since Java tends to provide best features for its developers, it offers object Cloning with cloneable interface in java.

What is Object Cloning?

Object Cloning is making the exact field to field copy of an object but with a different name assigned to it. The cloned object also has its separate memory space where it copies the content of the original object thus making changes in the content of the original object after cloning does not reflect in the clone object.

The cloneable interface in java

The cloneable interface in java is a marker interface that was introduced way back in JDK 1.0. It offers a method called clone() defined in the Object class that is used for cloning.  Syntax of the clone() method is as follows:

1.	protected Object clone() throws CloneNotSupportedException  

 The cloneable interface in java allows the implementing class to clone its objects without needing to use the new operator. 

The code below depicts the use of the cloneable interface in java,

1.	class Employee implements Cloneable{
2.	int empID;
3.	String name;
4.	Employee(int empID,String name){
5.	this.empID = empID;
6.	this.name = name;
7.	}
8.	public Object clone()throws CloneNotSupportedException{
9.	return super.clone();
10.	} 
11.	public static void main(String args[]){
12.	try{
13.	Employee e1 = new Employee (1000,"Sam William");
14.	Employee e2 = (Employee)e1.clone();
15.	System.out.println(e1.empID+" "+e1.name);
16.	System.out.println(e2.empID+" "+e2.name);
17.	}
18.	catch(CloneNotSupportedException c){} 
19.	}
20.	}

Output:

1000 Sam William 
1000 Sam William   

In the above-mentioned example, both reference variables have the same value. Thus, the clone() just copies the values of one object to another. In bigger projects. It can save some significant time for developers in writing the explicit code for copying the value as well. The extra processing required for copying would be eliminated as well. (The exception mentioned in the code above will be discussed later in this article.)

New operator vs cloneable interface in java

The New operator in java is used to instantiates a class by allocating some memory for a newobject and returning a reference to the allocated memory. It is also used to create the array object.  The problem arises when the new operator is used repeatedly in the code. As it is a pretty expensive operation especially when you are creating complex objects, it would take more processing time, first for allocating memory and then for copying every field one by one.

Being a good programmer, you know cannot afford to do that, this is where cloneable interface comes into play, Clone() creates a new instance of the same class and directly copies all the fields to the new instance. it saves the extra processing that would be used in the first allocation and then in copying the values. Clone() method also proves to be the fastest way for copying object array.

Look out for these Issues in the cloneable interface in java

Along with all the time efficiency, the cloneable interface has some limitations. Following are some issues to be considered while using the cloneable interface in java.

· CloneNotSupportedException

The Cloneable interface in java defines no members. It is only used to indicate that a class allows a bitwise copy (a clone) of an object to be made. If a developer attempts to Clone an object which does not implement the Cloneable interface, it will throw an exception called CloneNotSupportedException. Hence, to allow cloning of an object instance, that object class must implement the Cloneable interface. 

See the code example below, here cloneable interface is not implemented,

1.	public class Employee {
2.	 int empID;  
3.	 String name;
4.	Employee(int empID,String name){
5.	this.empID = empID;
6.	this.name = name;
7.	}
8.	   public String getName() {
9.	    return name;
10.	   }  
11.	   public static void main(String[] args) {
12.	    Employee emp1 = new Employee(1000, "Sam Williams");
13.	    try {
14.	        Employee emp2 = (Employee) emp1.clone();
15.	        System.out.println(emp2.getName());
16.	    } catch (CloneNotSupportedException e) {
17.	        e.printStackTrace();
18.	    }
19.	   }
20.	} 

The above code will throw the following exception when executed,

1.	java.lang.CloneNotSupportedException: Employee
2.	    at java.base/java.lang.Object.clone(Native Method)
3.	    at Employee.main(Employee.java:16)

 As earlier mentioned, the Cloneable interface in java is a marker interface, which means it does not have any clone method specification. In the above code snippet, implementing Cloneable in this code would mean that an Employee class instance can be cloned and Object class’s clone method is legal for the Employee class to override.

Below mentioned code is how you can correctly clone an Employee class instance along with overriding the clone method of an object in the Employee class.

1.	public class Employee implements Cloneable {
2.	   int empID;  
3.	   String name;
4.	   Employee(int empID,String name){
5.	   this.empID = empID;
6.	   this.name = name;
7.	 }
8.	  
9.	    public String getName() {
10.	        return name;
11.	    }
12.	  
13.	    public Object clone()throws CloneNotSupportedException{  
14.	        return (Employee)super.clone();  
15.	    }
16.	     
17.	    public static void main(String[] args) {
18.	        Employee emp1 = new Employee(1000, "Sam Williams");
19.	        try {
20.	            Employee emp2 = (Employee) emp1.clone();
21.	            System.out.println(emp2.getName());
22.	        } catch (CloneNotSupportedException e) {
23.	            e.printStackTrace();
24.	        }
25.	    }
26.	} 

· Clone() creates a shallow copy:  

When the clone() method is used to create a clone of an object, it creates a shallow copy. In a shallow copy, All the fields of the original objects are copied as it is but, if the original object contains any objects as fields then only their references will be copied, not the complete objects. It means that since only references are copied, both the original and clone object will point to the same reference internally. If you do any changes to the data using the clone object, it will reflect in the original object as well.

Due to this, cloning can seriously affect your code in some cases. It can result in a lot of errors and would be difficult to debug as well if not properly monitored. For example. If an object opens an I/O stream for a file and it is then cloned, the clone object will also be capable of operating the same stream so if the stream is closed by the clone of the object while the first object might still attempt to write in a file, it will result in a file error.

It is possible to create a deep copy of an object but it required to manually modify the clone() method which will take more time and will ultimately defeat the purpose of using clone() to save time.

· Type Casting Clone() method:

As improper use of the cloneable interface in java can cause several problems, clone( ) method is declared as protected inside Object. The Clone method is not supposed to be directly used on any object, which is why it is intended to be overridden by the subclass. This means that it can be only be called from within a method defined by the class that implements the cloneable interface.

The following program implements Cloneable and defines the method cloneTest( ), which calls clone( ) in Object:

Demonstrate the clone() method.

1.	class TestClone implements Cloneable {
2.	 int intNum;
3.	 double doubleNum;
4.	 TestClone clone() {
5.	  try {
6.	  // call clone in Object.
7.	  return (TestClone) super.clone();
8.	 } 
9.	catch(CloneNotSupportedException e) {
10.	  System.out.println("Cloning is not allowed.");
11.	  return this;
12.	  }
13.	 }
14.	}
15.	class Demo {
16.	 public static void main(String args[]) {
17.	  TestClone num1 = new TestClone();
18.	  TestClone num2;
19.	  num1.intNum = 30;
20.	  num1.doubleNum = 29.88;
21.	  num2 = num1.clone(); // clone num1
22.	  System.out.println("num1: " + num1.intNum + " " + num1.doubleNum);
23.	  System.out.println("num2: " + num2.intNum + " " + num2.doubleNum);
24.	  }
25.	}

Here, the method cloneTest( ) calls clone( ) method in Object and returns the result. The clone object must be cast into its appropriate type (TestClone) as it cannot be directly used in an object.

To overcome this, It is possible to create a public clone() method that would clone any object. The following example overrides clone( ) method so that it can be called from anywhere outside of its class. To do this, the developer needs to use the access specifier to the “Public” with clone(), as shown in the code below,

1.	class TestClone implements Cloneable {
2.	 int intNum;
3.	 double doubleNum;
4.	 //clone() is overridden and is public.
5.	 public Object clone() {
6.	 try {
7.	 // now clone can be called in Object.
8.	 return super.clone();
9.	 } 
10.	 catch(CloneNotSupportedException e) {
11.	 System.out.println("Cloning is not allowed.");
12.	 return this;
13.	  }
14.	 }
15.	}
16.	 class Demo2 {
17.	 public static void main(String args[]) {
18.	 TestClone num1 = new TestClone();
19.	 TestClone num2;
20.	 num1.intNum = 40;
21.	 num1.doubleNum = 30.88;
22.	 // calling the clone() directly from object.
23.	 num2 = (TestClone) num1.clone();
24.	 System.out.println("num1: " + num1.intNum + " " + num1.doubleNum);
25.	 System.out.println("num2: " + num2.intNum + " " + num2.doubleNum);
26.	 }
27.	} 

All these issues caused by cloning are sometimes difficult to identify. A top programmer would always suggest that despite its advantages, developers should not implement Cloneable interface in java without any good reason.

See Also: How To Fix An Illegal Start Of Expression In Java

Alternatives for copying object:

Following are some notable alternatives of Cloneable interface in java,

· Copy Constructors

One option that provides copy functionality for your class instead of using Cloneable is to use a copy constructor instead. A copy constructor is similar to any regular constructor, which returns a new instance of the class. As an input, it takes an object, which is supposed to be copied and returns a copy of it but the developer has to implement the custom cloning logic Inside the body of the constructor.

1.	public Employee(Employee employeeCopy) {
2.	    this.firstName = employeeCopy.firstName;
3.	    this.lastName = employeeCopy.lastName;
4.	    ...
5.	}

 The advantage would be that it does not require to implement any interface and also does not throw CloneNotSupportedException so exception handling won’t be required for it.

· Static Factory Methods

This is another very similar approach to copy constructors and has similar advantages. The only difference here is that instead of a constructor, a Static Factory Methods which takes an object to be copied as an input and returns a copied instance.

1.	public static Employee CopyEmployee(Employee EmptoyeeToCopy) {
2.	    Employee employeeCopy = new Employee ();
3.	    copiedEmployee.firstName = EmptoyeeToCopy.firstName;
4.	    copiedEmployee.lastName = EmptoyeeToCopy.lastName;
5.	    ...
6.	    return copiedEmployee;
7.	}

· Serialization and Deserialization

A new instance can also be created by deserializing a previously serialized object. The developer can serialize an object and then immediately deserialize it to create a copy. There are also some libraries that support cloning using serialization and deserialization however just like cloneable interface, It required to implement Serializable and it is also the most expensive method for copying.

· Reflection

Reflection is yet another process for making a copy of an object. Using reflection, a developer can read all the fields of a class, copy them and can assign them to a new instance even if the fields are not publicly accessible. There are numerous libraries now available that provides this functionality.

Conclusion

As we discussed, there are a lot of ways of making a copy of an object. The cloneable interface in Java is one of the most efficient among them. Cloning seems a very simple and basic feature but it aims to save a lot of time and processing in bigger projects. The only concern is that it should be implemented correctly and only when it required to fully take advantage of it. The developers first must understand the proper working, its implications and in what areas problems could arise before using the Cloneable interface in Java. It is a handy feature of java but must be used properly.

Author

Shaharyar Lalani is a developer with a strong interest in business analysis, project management, and UX design. He writes and teaches extensively on themes current in the world of web and app development, especially in Java technology.

Write A Comment