Site icon JavaGoal

Cloning in Java

Cloning in Java is an important topic for developers. By the use of cloning, we can create an exact copy of an Object.  It creates a new instance of the class of the current object and initializes it. It always creates a new object(Cloned object) with exactly the contents of the current object.

Let’s say mobile is an Object and we want to clone it. It means we want to create an exact copy of the mobile.

In this article, we will discuss How we can achieve Cloning by use of the clone() method and what is the clone() method in java. It is the most important question in the interview. Most of us already know about cloning but in this article, we will discuss some unique things about cloning.
Here is the table content of the article will we will cover this topic.

1. What is the clone() method in Java?
2. What is Cloning in Java?
3. How to use the clone() method?
4. How does the clone() method work?
5. How does JVM work with default cloning?
6. Types of Cloning
7. Shallow Cloning(With Memory representation)
8. Deep Cloning (With Memory representation)
9. How to achieve Deep cloning?

10. Advantages of cloning

What is the clone() method in Java?

clone() method is defined in Object class which is the super most class in Java. This method is used to create an exact copy of an object. It creates a new object and copies all data of the given object to that new object.

Let’s have a look at the code.

protected native Object clone() throws CloneNotSupportedException;

It is a native method. By means of the native method, it is written in C/C++ language.

What is Cloning in Java?

Java provides a way to create the exact copy of the Object. Let’s say you have an object with various properties. Now you want to create a new object with the same properties and values. Then you should use the cloning concept of Java.
Some programmers misunderstood the cloning concept with the assignment operator(=). Java doesn’t provide any operator to create a copy of an object.
If you use the assignment operator(=) then it will create a copy of the reference variable and not the object.

Student object1 = new Student();
Student object2 = object1;

By the use of the assignment operator object1 and object2 point to the same location, if any changes in object2 will be reflected in object1.

Let’s discuss it with an example

class Student
{
	int rollNo;
	String name;
}

public class Data
{
	public static void main(String[] args) 
	{
		Student object1 = new Student();
		object1.name = "Ravi";
		object1.rollNo = 1;
		
		Student object2 = object1;
		// Changing the value in object2 
		object2.name = "Ram";
		object2.rollNo = 2;
		
		System.out.println("Printing values from Object1:");
		System.out.println("Name:"+object1.name + " RollNo:"+ object1.rollNo);
		System.out.println("Printing values from Object2:");
		System.out.println("Name:"+object2.name + " RollNo:"+ object2.rollNo);
		
	}
}

Output: Printing values from Object1:
Name:Ram RollNo:2
Printing values from Object2:
Name:Ram RollNo:2

As you can see in the above example, both references(object1 and object2) are holding the same value because they are pointing to the same object.

This issue is solved by the clone() method because it creates a new object and both objects remain independent.

class Student implements Cloneable
{
	int rollNo;
	String name;
	public Object clone() throws CloneNotSupportedException 
	{ 
		return super.clone(); 
	} 
}


public class Data
{
	public static void main(String[] args) throws CloneNotSupportedException 
	{
		Student object1 = new Student();
		object1.name = "Ravi";
		object1.rollNo = 1;
		
		Student object2 = (Student) object1.clone();
		
		System.out.println("Printing values from Object1:");
		System.out.println("Name:"+object1.name + " RollNo:"+ object1.rollNo);
		System.out.println("Printing values from Object2:");
		System.out.println("Name:"+object2.name + " RollNo:"+ object2.rollNo);

		
		// Changing the value in object2 
		object2.name = "Ram";
		object2.rollNo = 2;

		System.out.println("After changes in values");
		System.out.println("Printing values from Object1:");
		System.out.println("Name:"+object1.name + " RollNo:"+ object1.rollNo);
		System.out.println("Printing values from Object2:");
		System.out.println("Name:"+object2.name + " RollNo:"+ object2.rollNo);
	}
}

Output: Printing values from Object1: Name:Ravi RollNo:1
Printing values from Object2:Name:Ravi RollNo:1
After changes in values
Printing values from Object1: Name:Ravi RollNo:1
Printing values from Object2: Name:Ram RollNo:2

The clone() method creates a copy by creating a new object and then copying the fields.
NOTE: If the class has only primitive data type members then it creates a new copy of each data member of the object. But if the class contains a reference data type member also then it doesn’t create a new copy of the reference member(It just creates a new copy of primitive). The member references in both the original object as well as the cloned object refer to the same object. In that case, both the original object and copy of the object (Cloned object) will point to the same object in the heap. This is known as a shallow copy.

How to use the clone() method?

1.  If you want to use cloning in Java, you must have to override the clone() method in your class. As you already know clone() method exists in the Object class its availed in each class you can override it.
2. To use the clone() method, we must implement the Cloneable interface which exists is java.lang package. It is a marker interface that is used to tell the JVM that we can perform a clone on our object. If we are not using the Cloneable interface, then the JVM will throw CloneNotSupportedException when we will call the clone() method.
3. Whenever we are overriding the clone() method, we need to call the clone() method of the superclass also. It will make a call its super’s clone(). This chain will continue until it reaches the clone() method of the Object class.

Important points about cloning:

1. The object which is returned by the clone() method is an exact copy of the original object. The copied object is known as a clone of the original object. Original and clone are two separate objects in heap memory. The below statement will return false.

// It returns false, because both are different object in heap memory
 a.clone() == a; 

2. The clone() method returns an exact copy of the original object.

// It returns true, because both object contains same values
x.clone().equals(x);

How does the clone() method work?

The Object class provides the default implementation of the clone() method.

Step 1:  The JVM checks whether the class implements the Cloneable interface, which is a marker interface. If the class doesn’t implement Cloneable Interface then it throws CloneNotSupportedException.
Step 2:
JVM checks the checked exception, which is always required to be handled while cloning an object.
Step 3: The Object.clone() method creates a shallow copy of the object and returned it to the caller. It copies all the content from one object to another object.

How does JVM work with default cloning?

So, JVM when called for cloning(Shallow cloning), does the following things:
1. If the class has only primitive data type members, then a completely new copy of the object will be created and the reference to the new object copy will be returned.
2. If the class contains members of any class type, then only the object references to those members are copied and hence the member references in both the original object as well as the cloned object refer to the same object.

Types of Cloning

There are two types of cloning.
1. Shallow cloning
2. Deep cloning

1. Shallow Cloning

Default implementation provided by Object.clone() is using shallow copy. In Shallow cloning, the clone() method creates a new object and copies all fields of the cloneable object to that new object.
It creates a new copy of the field if it is primitive. If the field reference types, then only the references of that object will be cloned instead of new object creation. Therefore, the reference variable of both objects will point to the same object.

Let’s discuss it with an example

class Address
{
	int pinCode;
	String city;
	Address()
	{	}
	Address(int pinCode, String city)
	{
		this.pinCode = pinCode;
		this.city = city;
	}
}


class Student implements Cloneable
{
	int rollNo;
	String name;
	Address address = new Address();
	public Object clone() throws CloneNotSupportedException 
	{ 
		return super.clone(); 
	} 
}


public class Data
{
	public static void main(String[] args) throws CloneNotSupportedException 
	{
		Student object1 = new Student();
		object1.name = "Ravi";
		object1.rollNo = 1;
		object1.address = new Address(101, "CHD");
		
		Student object2 = (Student) object1.clone();
		
		System.out.println("Printing values from Object1:");
		System.out.println("Name:"+object1.name + " RollNo:"+ object1.rollNo);
		System.out.println("Address:"+ object1.address.pinCode + " and " + object1.address.city);
		System.out.println("Printing values from Object2:");
		System.out.println("Name:"+object2.name + " RollNo:"+ object2.rollNo);
		System.out.println("Address:"+ object2.address.pinCode + " and " + object2.address.city);

		System.out.println("Is both object are same in heap memory:" + (object1 == object2));
		System.out.println("Is both Address object are same in heap memory:"+(object1.address == object2.address));
		
	}
}

Output: Printing values from Object1: Name:Ravi RollNo:1
Address:101 and CHD
Printing values from Object2: Name:Ravi RollNo:1
Address:101 and CHD
Is both object are same in heap memory: false
Is both Address object are same in heap memory:true

Any changes made in the referenced object(Address) in object object1 or object2 will be reflected in other objects.

class Address
{
	int pinCode;
	String city;
	Address()
	{	}
	Address(int pinCode, String city)
	{
		this.pinCode = pinCode;
		this.city = city;
	}
}


class Student implements Cloneable
{
	int rollNo;
	String name;
	Address address = new Address();
	public Object clone() throws CloneNotSupportedException 
	{ 
		return super.clone(); 
	} 
}


public class Data
{
	public static void main(String[] args) throws CloneNotSupportedException 
	{
		Student object1 = new Student();
		object1.name = "Ravi";
		object1.rollNo = 1;
		object1.address = new Address(101, "CHD");
		
		Student object2 = (Student) object1.clone();
		
		object2.name = "Ram";
		object2.rollNo = 2;
		object2.address.city = "KUK";
		object2.address.pinCode = 505;
		
		System.out.println("Printing values from Object1:");
		System.out.println("Name:"+object1.name + " RollNo:"+ object1.rollNo);
		System.out.println("Address:"+ object1.address.pinCode + " and " + object1.address.city);
		System.out.println("Printing values from Object2:");
		System.out.println("Name:"+object2.name + " RollNo:"+ object2.rollNo);
		System.out.println("Address:"+ object2.address.pinCode + " and " + object2.address.city);

}
}

Output: Printing values from Object1:Name:Ravi RollNo:1
Address:505 and KUK
Printing values from Object2:Name:Ram RollNo:2
Address:505 and KUK

2. Deep Cloning

As you saw in Shallow cloning the reference type member shares the reference of the object instead of creating a new object.
But in deep cloning, copying everything from one object to another object(Primitive and reference data members). In deep cloning, the cloned object is independent of the original object, and making changes in the cloned object should not affect the original object.

If we want to create deep cloning of object object1 then a new copy of each referenced member is created and these references are placed in object object2. The reference member of both objects will not point to the same object. This means any changes made in the referenced object member in Object object1 or object2 will be reflected in the other.

How to achieve Deep cloning?

To support deep cloning, we need to implement a Cloneable interface and override the clone() method in every reference type member that is linked to our object hierarchy. Then, we call super.clone() and these clone() methods in our object’s clone() method.

Let’s try to understand it with an example

class Address implements Cloneable
{
	int pinCode;
	String city;
	Address()
	{	}
	Address(int pinCode, String city)
	{
		this.pinCode = pinCode;
		this.city = city;
	}
	public Object clone() throws CloneNotSupportedException 
	{ 
		return super.clone(); 
	} 
}


class Student implements Cloneable
{
	int rollNo;
	String name;
	Address address = new Address();
	public Object clone() throws CloneNotSupportedException 
	{ 
		return super.clone(); 
	} 
}


public class Data
{
	public static void main(String[] args) throws CloneNotSupportedException 
	{
		Student object1 = new Student();
		object1.name = "Ravi";
		object1.rollNo = 1;
		object1.address = new Address(101, "CHD");
		
		Student object2 = (Student) object1.clone();
		object2.address = (Address) object1.address.clone();
		
		System.out.println("Printing values from Object1:");
		System.out.println("Name:"+object1.name + " RollNo:"+ object1.rollNo);
		System.out.println("Address:"+ object1.address.pinCode + " and " + object1.address.city);
		System.out.println("Printing values from Object2:");
		System.out.println("Name:"+object2.name + " RollNo:"+ object2.rollNo);
		System.out.println("Address:"+ object2.address.pinCode + " and " + object2.address.city);

		System.out.println("Is both object are same in heap memory:" + (object1 == object2));
		System.out.println("Is both Address object are same in heap memory:"+(object1.address == object2.address));
		
	}
}

Output: Printing values from Object1: Name:Ravi RollNo:1
Address:101 and CHD
Printing values from Object2: Name:Ravi RollNo:1
Address:101 and CHD
Is both object are same in heap memory:false
Is both Address object are same in heap memory:false

Now (object1.address == object2.address) will evaluate false because, in the clone() method of the Data class, we are cloning the address object and assigning it to the new cloned object.
As you see from the output of the above program both references are pointing to different objects in a heap even though both objects have the same data values.

System.out.println("Is both Address object are same in heap memory:"+(object1.address == object2.address));

Any changes made in the referenced object(Address) in object object1 or object2 will not be reflected in another object.

class Address implements Cloneable
{
	int pinCode;
	String city;
	Address()
	{	}
	Address(int pinCode, String city)
	{
		this.pinCode = pinCode;
		this.city = city;
	}
	public Object clone() throws CloneNotSupportedException 
	{ 
		return super.clone(); 
	} 
}


class Student implements Cloneable
{
	int rollNo;
	String name;
	Address address = new Address();
	public Object clone() throws CloneNotSupportedException 
	{ 
		return super.clone(); 
	} 
}


public class Data
{
	public static void main(String[] args) throws CloneNotSupportedException 
	{
		Student object1 = new Student();
		object1.name = "Ravi";
		object1.rollNo = 1;
		object1.address = new Address(101, "CHD");
		
		Student object2 = (Student) object1.clone();
		
		object2.name = "Ram";
		object2.rollNo = 2;
		object2.address = (Address) object1.address.clone();
		object2.address.city = "KUK";
		object2.address.pinCode = 505;
		
		System.out.println("Printing values from Object1:");
		System.out.println("Name:"+object1.name + " RollNo:"+ object1.rollNo);
		System.out.println("Address:"+ object1.address.pinCode + " and " + object1.address.city);
		System.out.println("Printing values from Object2:");
		System.out.println("Name:"+object2.name + " RollNo:"+ object2.rollNo);
		System.out.println("Address:"+ object2.address.pinCode + " and " + object2.address.city);

		
	}
}

Output: Printing values from Object1: Name:Ravi RollNo:1
Address:101 and CHD
Printing values from Object2:Name:Ram RollNo:2
Address:505 and KUK

Advantages of cloning

1. If we want to create an exact copy of the object without cloning we need to write the code again. By the use of Cloning, we don’t need to write repetitive codes. We just need to implement the interface and override the clone() method in the class.
2. Let’s say your project is already developed and you want to create a copy of the object for some changes. Then cloning will be the easiest and most efficient way of copying objects.
3. Cloning is the fastest way to copy an array.
4. More effective than Copy constructors. In the copy constructor, we have to copy all of the data over explicitly. It means we must reassign all the data members (Fields) of the class in the constructor. But by use of the clone() method, we can do this work within 4- or 5-line.

Exit mobile version