Do you think IIT Guwahati certified course can help you in your career?
No
Introduction
You must have faced a situation in which you need to copy the contents of an object to a new object in such a way that changing the variables of any one object does not affect the other. As you have noticed, simply using the assignment operator does not provide the desired result.
In this blog, we will discuss the clone() method of Object class to achieve the required results.
What is Object Cloning in Java?
Object cloning in Java refers to the process of creating a new instance (or copy) of an existing object. This is achieved by duplicating the state of the original object so that the new object is an identical copy but located at a different memory address.
Java provides a clone() method, which is defined in the Object class. By default, this method performs a shallow copy of the object, meaning it copies the object's reference fields but does not copy the objects referenced by those fields. However, if deep copying is needed, custom cloning logic can be implemented to ensure that referenced objects are also cloned.
Why Do We Need Cloning?
Object cloning is essential in many real-world applications where creating an exact copy of an existing object is more efficient than building a new one from scratch. Cloning is particularly useful when an object has a complex structure or a deeply nested state that would take significant time and resources to recreate manually. For example, in video games, duplicating a character or weapon with the same attributes (like power, speed, or position) is faster through cloning, allowing the game to generate similar objects quickly without reinitializing all properties.
Cloning also plays a key role in preserving the current state of an object. In scenarios like session management or undo operations in text editors, cloning can capture a snapshot of an object’s state, which can later be restored if needed. Additionally, the Prototype Design Pattern heavily relies on cloning to create new objects based on a predefined template, promoting faster object creation and reducing system overhead.
A relatable analogy is copying a document: instead of rewriting the entire content, you simply duplicate the file, saving time and effort. Similarly, cloning allows programs to work more efficiently by reusing existing objects while maintaining their integrity and state.
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
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;
//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
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
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
Java
class Employee implements Cloneable {
String name; int salary;
public Employee(String name, int salary) { this.name = name; this.salary = salary; }
//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
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
In this example, person2 is a clone of person1, with the same field values but located at a different memory address.
Shallow vs Deep Cloning: Key Differences in Java
Key Differences Between Shallow and Deep Cloning
In Java, cloning is a mechanism to create a copy of an existing object. However, not all cloning is the same. The two primary types are shallow cloning and deep cloning, and they differ significantly in how they handle object references.
Shallow Cloning
What it does: Shallow cloning creates a new object but copies only the top-level structure. It does not create new copies of the objects referenced inside the original object. Instead, it copies the references, meaning both the original and the cloned object share the same nested objects.
Memory Impact: More memory-efficient since it doesn't duplicate nested objects.
When to Use: Suitable when objects contain immutable fields or when shared references are acceptable.
Deep Cloning
What it does: Deep cloning creates a fully independent copy of the object, including all nested or referenced objects. It recursively clones all levels of the object graph.
Memory Impact: Requires more memory and processing time since it duplicates the entire object structure.
When to Use: Essential when objects have mutable nested references and changes in the clone should not affect the original object.
Use Case: Deep cloning is recommended when objects contain mutable nested objects, and independent copies are required (e.g., session snapshots, prototype objects in complex systems).
Practical Tips:
Use shallow cloning for simple, flat objects or when nested data is immutable.
Use deep cloning when working with nested, mutable objects to prevent unintended side effects.
Be cautious: shallow clones can cause hard-to-find bugs if shared references are modified unexpectedly.
For complex cloning, libraries like Apache Commons Lang SerializationUtils or using JSON serialization can simplify deep cloning tasks.
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.
Best Practices for Object Cloning in Java
When to Use Cloning
Object cloning in Java is particularly useful when you need to create exact copies of existing objects while preserving their current state. It helps avoid unintended side effects that occur when multiple objects share references to mutable fields. Cloning is often preferred in situations where creating a new object from scratch would be resource-intensive or complex, especially when the object has deeply nested structures or holds a significant amount of data.
Cloning is also beneficial when you want to quickly duplicate an object to perform independent modifications without affecting the original. This is common in game development (duplicating players or enemies), session management (preserving a user’s state), and prototype-based design patterns, where new objects are frequently created based on a predefined template.
However, cloning should not be overused. It is most appropriate when:
You need a fast copy mechanism.
The object is large and costly to recreate.
The object is part of a prototype pattern.
The copied object must be fully independent (especially in deep cloning scenarios).
Alternatives to Cloning
While cloning can be useful, it is not always the best approach. Java offers several alternatives that are often safer, more readable, and easier to maintain:
1. Copy Constructors
A copy constructor is a constructor that accepts an object of the same class and manually copies its fields.
public Person(Person other) {
this.name = other.name;
this.address = new Address(other.address);
}
Pros:
Safer and more explicit control over how the copy is made.
Easier to understand and debug.
Cons:
Requires writing extra code for each class.
2. Factory Methods
Factory methods can be used to create object copies.
Person clone = PersonFactory.clonePerson(originalPerson);
Pros:
Allows complex logic during object creation.
Supports object pooling or customization.
Cons:
Adds design complexity if overused.
3. Serialization-Based Copying
Deep cloning can be achieved by serializing and deserializing an object. Pros:
Useful for fully automating deep copies without manual field copying.
Cons:
Performance overhead due to I/O operations.
Requires all involved classes to be serializable.
4. Third-Party Libraries
Libraries like Apache Commons Lang’s SerializationUtils can simplify deep cloning.
Person cloned = SerializationUtils.clone(originalPerson);
Pros:
Quick and less error-prone.
Saves development time for complex objects.
Cons:
May introduce external dependencies.
Can have performance costs.
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 CloneNotSupportedExceptionwould 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.