Problem with ‘=’ Operator
When we copy an object to a new object using the ‘=’ (assignment) operator, it simply creates a copy of reference variables. The original and the copy are references to the same object. Any change in one object affects the other as well, which is not desired.
The Clone Method
The clone() method is used to solve the issue and achieve the desired results. We must use the clone() method if we want a copy to be a new object that starts off identical to the original but whose state can change over time, independent of the original object.
The clone() method eliminates the need for additional processing when making an exact copy of an object. It will take a lot of effort if we do it with the new keyword, therefore we may utilise object cloning instead. The clone method creates an exact copy of an object for which it has been invoked in a field-by-field assignment order and will return the new object reference.
The Cloneable interface must be implemented by a class whose object clone to create. If we do not implement Cloneable interface, clone() method generates CloneNotSupportedException.
Types of Cloning in Java
Cloning in Java can be grouped into two categories:
- Shallow Cloning
- Deep Cloning
Shallow Cloning
Shallow Cloning is a term used in Java to describe the cloning process that uses the clone() method. In shallow cloning, if the original object has references to other objects as fields, only those references will be cloned rather than a new object being created. In other words, if you change the parameters of objects that are referenced in the original object, it will get reflected in both the objects (original and cloned one). As a result, shallow cloning is constrained by the original object. We will now see an example to see the above concept in action.
Implementation
Java
class Employee {
String name;
int salary;
public Employee(String name, int salary) {
this.name = name;
this.salary = salary;
}
}
class Company implements Cloneable {
int companyID;
String companyName;
Employee Employee;
public Company(int companyID, String companyName, Employee Employee) {
this.companyID = companyID;
this.companyName = companyName;
this.Employee = Employee;
}
//Default version of clone() method
protected Company clone() throws CloneNotSupportedException {
return (Company) super.clone();
}
}
public class ShallowCloning {
public static void main(String[] args) {
Employee emp = new Employee("Rahul", 50000);
Company company1 = new Company(0, "CodingNinjas", emp);
Company company2 = null;
try {
//Creating a clone of company1 and assigning it to company2
company2 = (Company) company1.clone();
company2.companyID = 1;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
//Printing Details of company1
System.out.println("Details of Company 1: \n");
System.out.println("Id: " + company1.companyID);
System.out.println("Name: " + company1.companyName);
System.out.println("Course Id: " + company1.Employee.name + "\n\n");
//Printing Details of company2
System.out.println("Details of Company 2: \n");
System.out.println("Id: " + company2.companyID);
System.out.println("Name: " + company2.companyName);
System.out.println("Course Id: " + company2.Employee.name+"\n\n");
//Changing the salary of employee of company2
System.out.println("Changing the salary of employee of company 2 to 60,000");
company2.Employee.salary = 60000;
System.out.println("Salary of Employee of company2: "+company2.Employee.salary+"\n\n");
//This change will be reflected in original 'company1'
System.out.println("Updated Details of Company 1:");
System.out.println("Name of employee of Company 1: "+company1.Employee.name);
System.out.println("Salary of employee of Company 1: "+company1.Employee.salary);
}
}

You can also try this code with Online Java Compiler
Run Code
Output:
Details of Company 1:
Id: 0
Name: CodingNinjas
Course Id: Rahul
Details of Company 2:
Id: 1
Name: CodingNinjas
Course Id: Rahul
Changing the salary of employee of company 2 to 60,000
Salary of Employee of company2: 60000
Updated Details of Company 1:
Name of employee of Company 1: Rahul
Salary of employee of Company 1: 60000
Practice by yourself on java online compiler.
Deep Cloning
Deep Cloning is a term used in Java to describe the cloning process that uses the clone() method with added functionality. In deep cloning, if the object to be cloned references other objects as field parameters, those objects are cloned as well. In other words, changes in the parameters of objects that are referenced in the original object will not get reflected in the other one. As a result, deep cloning is not constrained by the original object. This makes the cloned object independent of the original object and any changes made in any of the objects won’t be reflected on the other. We will now see an example to see the above concept in action.
Implementation
Java
class Employee implements Cloneable {
String name;
int salary;
public Employee(String name, int salary) {
this.name = name;
this.salary = salary;
}
protected Employee clone() throws CloneNotSupportedException {
return (Employee)super.clone();
}
}
class Company implements Cloneable {
int companyID;
String companyName;
Employee Employee;
public Company(int companyID, String companyName, Employee Employee) {
this.companyID = companyID;
this.companyName = companyName;
this.Employee = Employee;
}
//Default version of clone() method
protected Company clone() throws CloneNotSupportedException {
Company copy = (Company) super.clone();
copy.Employee = copy.Employee.clone();
return copy;
}
}
public class ShallowCloning {
public static void main(String[] args) {
Employee emp = new Employee("Rahul", 50000);
Company company1 = new Company(0, "CodingNinjas", emp);
Company company2 = null;
try {
//Creating a clone of company1 and assigning it to company2
company2 = (Company) company1.clone();
company2.companyID = 1;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
//Printing Details of company1
System.out.println("Details of Company 1: \n");
System.out.println("Id: " + company1.companyID);
System.out.println("Name: " + company1.companyName);
System.out.println("Course Id: " + company1.Employee.name + "\n\n");
//Printing Details of company2
System.out.println("Details of Company 2: \n");
System.out.println("Id: " + company2.companyID);
System.out.println("Name: " + company2.companyName);
System.out.println("Course Id: " + company2.Employee.name + "\n\n");
//Changing the salary of employee of company2
System.out.println(
"Changing the salary of employee of company 2 to 60,000"
);
company2.Employee.salary = 60000;
System.out.println(
"Salary of Employee of company2: " + company2.Employee.salary + "\n\n"
);
//This change will be reflected in original 'company1'
System.out.println("Updated Details of Company 1:");
System.out.println(
"Name of employee of Company 1: " + company1.Employee.name
);
System.out.println(
"Salary of employee of Company 1: " + company1.Employee.salary
);
}
}

You can also try this code with Online Java Compiler
Run Code
Output:
Details of Company 1:
Id: 0
Name: CodingNinjas
Course Id: Rahul
Details of Company 2:
Id: 1
Name: CodingNinjas
Course Id: Rahul
Changing the salary of employee of company 2 to 60,000
Salary of Employee of company2: 60000
Updated Details of Company 1:
Name of employee of Company 1: Rahul
Salary of employee of Company 1: 50000
Also see, Duck Number in Java
Example of clone() method (Object cloning)
Here’s an example demonstrating how to use the clone() method in Java for object cloning:
Java
class Person implements Cloneable {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone(); // Calls Object's clone() method
}
public static void main(String[] args) {
try {
// Creating an object of Person
Person person1 = new Person("Rahul", 30);
// Cloning person1 to create person2
Person person2 = (Person) person1.clone();
// Displaying values of person1 and person2
System.out.println("Person 1: " + person1.name + ", " + person1.age);
System.out.println("Person 2: " + person2.name + ", " + person2.age);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}

You can also try this code with Online Java Compiler
Run Code
Output:
Person 1: Rahul, 30
Person 2: Rahul, 30
In this example, person2 is a clone of person1, with the same field values but located at a different memory address.
Advantage of Object Cloning
- Efficiency: Cloning can be a faster way to create copies of objects, as it avoids the need to recreate all the data from scratch.
- State Preservation: Cloning preserves the state of the original object, which is useful when you need an exact replica.
- Independent Objects: The clone method creates a new object, ensuring that modifications to the clone do not affect the original object.
- Object Copying: Allows easy copying of objects with complex structures when deep cloning is used.
Disadvantage of Object Cloning
- Shallow Copy Issues: By default, the clone() method creates a shallow copy. This can be problematic when the object contains references to other mutable objects, leading to unexpected behavior due to shared references.
- Performance Overhead: Cloning large or complex objects (especially when deep cloning is required) can introduce performance overhead, as the entire object structure must be duplicated.
- Exception Handling: Since the clone() method may throw a CloneNotSupportedException, developers need to handle this exception, which adds complexity to the code.
- Unwanted Copying of State: Some objects might not be suitable for cloning because their state is dependent on runtime conditions or external resources, making cloning inappropriate or causing issues.
Frequently Asked Questions
What is cloning in Java?
Object cloning is a way to create an exact copy of an object. The clone() method of Object class is used to clone an object. The java. lang. Cloneable interface must be implemented by the class whose object clone we want to create.
Is a Java clone a deep copy?
clone() is indeed a shallow copy. However, it's designed to throw a CloneNotSupportedException unless your object implements Cloneable . And when you implement Cloneable, you should override clone() to make it do a deep copy, by calling clone() on all fields that are themselves cloneable.
What happens when a class does not implement a Cloneable class and tries to clone its objects?
The CloneNotSupportedException would be thrown.
Why do we override the clone method?
We override the clone method() of the object class and declare it protected so that it is accessible only to the subclasses of the current class.
Conclusion
In this blog, we understood the topic of object cloning in great detail. We extensively explored the concepts of cloning in Java by going through both types of cloning namely shallow and deep cloning. We also discussed the problem with the assignment operator and discussed the Cloneable interface as well. We saw the concepts taught in this blog in action with the help of examples.
We hope that this blog has helped you enhance your knowledge regarding testing using Mocha. If you would like to learn more, head over to our practice platform Code360 to practice top problems, attempt mock tests, read interview experiences, and much more.