In Java, cloning is a process in which we create an exact copy (clone) of an object. For example, an object containing a list has values {3,5,7}, so the cloned object also contains the same values as the original object {3, 5, 7}. The clone() method in the Object class is used for performing the cloning of an object.
Note: If we are cloning an object, then the class must have implemented the Cloneable interface otherwise, it throws CloneNotSupportedException.
Types of Cloning in Java
There are two types of cloning or copying in Java mentioned below:
1. Shallow Cloning
Shallow cloning in Java creates a new object, but the new object that is created has the same reference as the original object, so instead of creating an actual copy, it involves copying the references.
Important Characteristics:
- Primitive fields: The primitive fields, such as int, char, or float in Java is copied by value. Which means their values are directly transferred to the clone object.
- Reference fields: The String, arrays, or custom objects are copied by reference. It means that both the original and cloned objects will point to the same memory location for the reference variable.
Example: Performing a shallow copy using the Clone() method.
Java
// Java program to show shallow cloning
class Address implements Cloneable
{
String city;
public Address(String city) {
this.city = city;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Geek implements Cloneable
{
String name;
int age;
Address address;
public Geek(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone(); // Shallow cloning
}
}
public class Main
{
public static void main(String[] args)
{
try {
Address address = new Address("Bhopal");
Geek p1 = new Geek("Geek", 35, address);
// Shallow clone
Geek p2 = (Geek) p1.clone();
System.out.println("Original Person: " + p1.name + ", " + p1.age + ", " + p1.address.city);
System.out.println("Cloned Person: " + p2.name + ", " + p2.age + ", " + p2.address.city);
// Modifying the original object's address and age
p1.address.city = "Noida";
p1.age = 30;
System.out.println("\nAfter modifying the original address:");
System.out.println("Original Person: " + p1.name + ", " + p1.age + ", " + p1.address.city);
System.out.println("Cloned Person: " + p2.name + ", " + p2.age + ", " + p2.address.city);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
OutputOriginal Person: Geek, 35, Bhopal
Cloned Person: Geek, 35, Bhopal
After modifying the original address:
Original Person: Geek, 30, Noida
Cloned Person: Geek, 35, Noida
Explanation: Here, we are performing shallow copying with the help of Clone() method and both the original and cloned object shared the same Address reference. When the original object address is changed so the changes are reflected on the cloned object as well. Primitive fields like age are copied by value, so changes in the original's age do not affect the clone.
2. Deep Cloning
Deep cloning refers to creating a complete, independent copy of an object, including copies of any referenced objects. Deep cloning is different from shallow cloning because it ensure that the original object do not share the references not even for the mutable fields.
Important Characteristics:
- The fields are recursively copied in deep cloning,lists including the mutable fields such as arrays, list and custom objects.
- Deep cloning is also called actual cloning because it creates fully independent copies of objects.
Example 2: Performing a Deep copy using the Clone() method.
Java
// Deep cloning in Java using clone() method
class Address implements Cloneable
{
String city;
public Address(String city) {
this.city = city;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Geek implements Cloneable
{
String name;
int age;
Address address;
public Geek(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
@Override
public Object clone() throws CloneNotSupportedException {
Geek cloned = (Geek) super.clone();
// Deep clone the address object
cloned.address = (Address) address.clone();
return cloned;
}
}
public class Main
{
public static void main(String[] args)
{
try {
Address address = new Address("Bhopal");
Geek p1 = new Geek("Geek", 35, address);
// Deep clone
Geek p2 = (Geek) p1.clone();
System.out.println("Original Person: " + p1.name + ", " + p1.age + ", " + p1.address.city);
System.out.println("Cloned Person: " + p2.name + ", " + p2.age + ", " + p2.address.city);
// Modifying the original object's address and age
p1.address.city = "Noida";
p1.age = 30;
System.out.println("\nAfter modifying the original address:");
System.out.println("Original Person: " + p1.name + ", " + p1.age + ", " + p1.address.city);
System.out.println("Cloned Person: " + p2.name + ", " + p2.age + ", " + p2.address.city);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
OutputOriginal Person: Geek, 35, Bhopal
Cloned Person: Geek, 35, Bhopal
After modifying the original address:
Original Person: Geek, 30, Noida
Cloned Person: Geek, 35, Bhopal
Explanation: Here, we are performing deep cloning with the help of Clone() method. The Geek class overrides the clone() method to also clone the Address object it contains and because of this the original and cloned objects have independent Address objects. So, changes to the original address do not affect the clone address.
Cloneable Interface
The cloneable interface is a an important interface to understand when we want to perform the cloning operation. The Cloneable is a marker interface ( without containing any fields or methods ) that indicates to the Java Virtual Machine (JVM) that an object of a class can be cloned. The cloneable interface is necessary to allow objects to be cloned using the clone() method of the object class.
Syntax:
class ClassName implements Cloneable {
// fields and methods
@override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
Important Characteristics:
- We need to implement the Cloneable interface because in Java the clone() method is protected in the Object class, It means we can not directly accessed unless the class explicitly implement the cloneable interface.
- If we try to use clone() method without implementing the Cloneable interface it throw a CloneNotSupportedException at runtime.
Example 3: Try to use Clone method without implementing the Cloneable Interface.
Java
// Java program to show CloneNotSupportedException
class Address
{
String city;
public Address(String city) {
this.city = city;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
// Do not implements Cloneable here
class Geek
{
String name;
int age;
Address address;
public Geek(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
}
public class Main
{
public static void main(String[] args)
{
try {
Address address = new Address("Bhopal");
Geek p1 = new Geek("Geek", 35, address);
// This will throw CloneNotSupportedException because Geek does NOT implement Cloneable
Geek p2 = (Geek) p1.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
}
Output:
Explanation: Here, the Geek class does not implement Cloneable and when we call Clone() method it throws a CloneNotSupportedException. To avoid this exception, the class must implement Cloneable
Shallow Cloning vs Deep Cloning
The table below demonstrates the difference between shallow cloning and deep cloning.
Aspect | Shallow Cloning | Deep Cloning |
---|
Mutable objects | It shares the same references | It creates independent copies of referenced objects |
---|
Object Reference | It only copies the reference, not the object. | It recursively copies all referenced objects |
---|
Complexity | It is simpler and faster | It is more complex and slower because of recursive copying. |
---|
Use Case | Suitable when shared objects are acceptable and does not require modification of objects. | Used when full independence between original and clone is required |
---|
Default Behaviour | Java's clone() performs shallow cloning by default | Requires manual handling (overriding clone()) for deep cloning |
---|
Important Points:
- Primitive fields behave the same in shallow and deep cloning because they are copied by value.
- Deep cloning creates a fully independent copy but is more complex and slower.
- Shallow cloning is faster but can cause unintended side effects when mutable objects are shared
Similar Reads
File Handling in Java
In Java, with the help of File Class, we can work with files. This File Class is inside the java.io package. The File class can be used to create an object of the class and then specifying the name of the file.Why File Handling is Required?File Handling is an integral part of any programming languag
6 min read
Coding Guidelines in Java
Java is one of the most popular and widely used programming languages and platforms. A platform is an environment that helps to develop and run programs written in any programming language. Java is fast, reliable, and secure. From desktop to web applications, scientific supercomputers to gaming cons
7 min read
Compiler Class in Java
Compiler Class provides support and related services to Java code to Native Code. Native code is a form of code that can be said to run in a virtual machine (for example, [JVM]Java Virtual Machine). Declaration: public final class Compiler extends ObjectMethods of Java Compiler Class 1. command() T
2 min read
Collections Class in Java
Collections class in Java is one of the utility classes in the Java Collections Framework. The java.util package contains the Collections class in Java. The Java Collections class is used with the static methods that operate on the collections or return the collection. All the methods of this class
13 min read
Java File Class
Java File class is a representation of a file or directory pathname. Because file and directory names have different formats on different platforms, a simple string is not adequate to name them. Java File class contains several methods for working with the pathname, deleting and renaming files, crea
6 min read
Java.io.Console class in Java
The Java.io.Console class provides methods to access the character-based console device, if any, associated with the current Java virtual machine. The Console class was added to java.io by JDK 6. Important Points: It is used to read from and write to the console, if one exists. Console is primarily
4 min read
Java Exception Handling
Exception handling in Java allows developers to manage runtime errors effectively by using mechanisms like try-catch block, finally block, throwing Exceptions, Custom Exception handling, etc.An Exception is an unwanted or unexpected event that occurs during the execution of a program (i.e., at runti
10 min read
What is Core Java?
Java is a programming language that is class-based and object-oriented. It is designed to be general-purpose and aims to have fewer implementation dependencies, and serves as a computing platform for application development. However, many new to the software industry often ask what Core Java is. Wha
7 min read
Execution Engine in Java
Java virtual machine or JVM can be visualized as a virtual machine residing in the computer that provides an environment for the code to get executed. Java Runtime Environment or JRE is an implementation of the JVM. In order to execute the code, an execution engine is used. In this article, let's un
3 min read
Network Input in Java
In Java, Network Input is all about sending and getting data over a network. It's about making links, getting data from input sources, and dealing with the information we get. Java offers strong tools, like input streams and sockets. These help with these operations so communication between devices
2 min read