Cloning is the process of creating an exact copy of an existing object.
In projects cloning is common requirement. For example, In e-commerce projects, we may place an order and we may duplicate the order. When we duplicate the order, we need to create clone of an existing order.
Steps to clone an Object
- Our class should implement java.lang.Cloneable interface
- Cloneable is a marker interface
- JVM throw CloneNotSupportedException if our object is not instanceof Cloneable
- Our class should override clone() method of java.lang.Object class
- To be frank we no need to override a clone() method. But we should define some method which contains cloning logic
- For example method signature could be public Object createCopy() throws CloneNotSupportedException { }
- To be frank we no need to override a clone() method. But we should define some method which contains cloning logic
- In our class overridden clone() method, we have to call java.lang.Object.clone() method, which is the actual worker who creates the clone of our object
- Object.clone() method creates a new instance and copies all fields bit-by-bit of original object to new instance
Let’s try to understand Java cloning with example. To demonstrate cloning we create two classes Employee and Department with
- toString() to show the content of objects
- equals() method to compare content of objects
- clone() to clone the object
- parameterized constructor to populated objects
- setters and getters
Example : Java clone
Employee.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
package com.vidvaan.corejava.cloning01.shallow; // Employee domain object public class Employee implements Cloneable { // primitive instance variables private int id; private String name; // reference variable // Department no need to implement Cloneable if we don't call clone method on it // Department need to implement Cloneable if we call clone method on it private Department department; public Employee() { } public Employee(int id, String name, Department department) { super(); this.id = id; this.name = name; this.department = department; } // Here we are overriding method from java.lang.Object @Override protected Object clone() throws CloneNotSupportedException { // super.clone() is the actual worker who creates the clone of our object. return super.clone(); } // Even we can have a method of our own and calls Object.clone() to clone Object public Object createCopy() throws CloneNotSupportedException { // super.clone() is the actual worker who creates the clone of our object. return super.clone(); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } @Override public String toString() { return "Employee [id=" + id + ", name=" + name + ", department=" + department + "]"; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Employee other = (Employee) obj; if (department == null) { if (other.department != null) return false; } else if (!department.equals(other.department)) return false; if (id != other.id) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } } |
Department.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
package com.vidvaan.corejava.cloning01.shallow; // Department domain class public class Department implements Cloneable { private int id; private String name; public Department() { } public Department(int id, String name) { super(); this.id = id; this.name = name; } // Here we are overriding method from java.lang.Object @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } // Even we can have a method of our own and calls Object.clone() to clone Object public Object createCopy() throws CloneNotSupportedException { return super.clone(); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Department [id=" + id + ", name=" + name + "]"; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Department other = (Department) obj; if (id != other.id) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } } |
JavaCloneDemo.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
package com.vidvaan.corejava.cloning01.shallow; // Java clone demo public class JavaCloneDemo { public static void main(String[] args) throws CloneNotSupportedException { // Let's create non Cloneable independent object Department originalDepartment = new Department(1234, "Sales"); // Let's create Cloneable dependent object Employee originalEmployee = new Employee(9999, "Sekhar", originalDepartment); // Lets create a clone of the original object Employee clonedEmployee = (Employee) originalEmployee.clone(); // Lets verify content of original and cloned object, content should be same System.out.println("originalEmployee: " + originalEmployee); System.out.println("clonedEmployee: " + clonedEmployee); // Must false, because original and cloned object have different memory address System.out.println("originalEmployee == clonedEmployee: " + (originalEmployee == clonedEmployee)); // Must true, because original and cloned object have same content System.out.println("originalEmployee.equals(clonedEmployee): " + originalEmployee.equals(clonedEmployee)); System.out.println("------Reference class(Employee.department)------"); // Here department object not cloned, both references are pointing to same // object, so content should be same System.out.println("originalEmployee.department: " + originalEmployee.getDepartment()); System.out.println("clonedEmployee.department: " + clonedEmployee.getDepartment()); // Must true, because original and cloned object have same memory address System.out.println("originalEmployee.department == clonedEmployee.department: " + (originalEmployee.getDepartment() == clonedEmployee.getDepartment())); // Must true, because original and cloned objects pointing to same object System.out.println("originalEmployee.department.equals(clonedEmployee.department): " + originalEmployee.getDepartment().equals(clonedEmployee.getDepartment())); // Let's modify cloned objects content and see whether original objects content // also modifies or not clonedEmployee.setName("ModifiedEmployeeName"); clonedEmployee.getDepartment().setName("ModifiedDepartmentName"); // Lets verify content after cloned is modified // cloned department modifications will modify original department data too // Because both original and cloned department references are pointing to same // department object System.out.println("-----After Employee.department cloned object modified------"); System.out.println("originalEmployee: " + originalEmployee); System.out.println("clonedEmp loyee: " + clonedEmployee); } } |
Output :
originalEmployee: Employee [id=9999, name=Sekhar, department=Department [id=1234, name=Sales]]
clonedEmployee: Employee [id=9999, name=Sekhar, department=Department [id=1234, name=Sales]]
originalEmployee == clonedEmployee: false
originalEmployee.equals(clonedEmployee): true
——Reference class(Employee.department)——
originalEmployee.department: Department [id=1234, name=Sales]
clonedEmployee.department: Department [id=1234, name=Sales]
originalEmployee.department == clonedEmployee.department: true
originalEmployee.department.equals(clonedEmployee.department): true
—–After Employee.department cloned object modified——
originalEmployee: Employee [id=9999, name=Sekhar, department=Department [id=1234, name=ModifiedDepartmentName]]
clonedEmp loyee: Employee [id=9999, name=ModifiedEmployeeName, department=Department [id=1234, name=ModifiedDepartmentName]]
Great, In the above example, we have added comments to explain each step of the code. Here observations are, all primitive instance variables are copied from original to cloned object successfully. But In the case of reference variables when we modify clonedEmployee.department.name then originalEmployee.department.name also modified(as shown in the above output). This means in the case of reference variables both originalEmployee.department and clonedEmployee.department are pointing to same object. This type of cloning is known as Shallow Cloning.
Types of Cloning
Cloning in Java can be grouped into two categories based on whether we are copying both primitive and reference variables data.
- Shallow Cloning
- Deep Cloning
Shallow Cloning
Shallow cloning is “default implementation” in Java. In overridden clone
method, if you are cloning only primitives but not all the object types, then this is called shallow cloning. In the above example what ever we implemented is called shallow cloning. The below image is the representation of shallow cloning of our example.

Deep Cloning
Deep Cloning means copying everything(both primitives and reference types) from one object to another object. To achieve this, we will need to modify our overridden clone() method of Employee class. Here the rule is all reference type also should implement Cloneable and override clone() method of java.lang.Object class.
In our previous example already both Employee and Department implement Cloneable interface and overridden clone() method of java.lang.Object class. But over previous Employee clone() method supports only shallow cloning. We have to modify Employee.clone() method as follows to support Deep cloning as shown below.
1 2 3 4 5 6 7 8 |
@Override protected Object clone() throws CloneNotSupportedException { // super.clone() is the actual worker who creates the clone of our object. Employee clone = (Employee) super.clone(); clone.setDepartment((Department) this.department.clone()); // Here we are making sure Department also gets cloned return clone; } |
As we modified overridden clone() method in Employee class to support Deep Cloning, Then re-run the test program JavaCloneDemo.java, then we can see the following output.
Deep Copy Output :
originalEmployee: Employee [id=9999, name=Sekhar, department=Department [id=1234, name=Sales]]
clonedEmployee: Employee [id=9999, name=Sekhar, department=Department [id=1234, name=Sales]]
originalEmployee == clonedEmployee: false
originalEmployee.equals(clonedEmployee): true
——Reference class(Employee.department)——
originalEmployee.department: Department [id=1234, name=Sales]
clonedEmployee.department: Department [id=1234, name=Sales]
originalEmployee.department == clonedEmployee.department: false
originalEmployee.department.equals(clonedEmployee.department): true
—–After Employee.department cloned object modified——
originalEmployee: Employee [id=9999, name=Sekhar, department=Department [id=1234, name=Sales]]
clonedEmp loyee: Employee [id=9999, name=ModifiedEmployeeName, department=Department [id=1234, name=ModifiedDepartmentName]]
With this output we can understand that, changing state of the cloned object does not affect the original object. This is called Deep cloning. The below image is the representation of Deep cloning of our example.

Advantages of Object.clone()
- Cloning requires much fewer lines of code
- It is the easiest and most efficient way for copying objects
- It is the fastest way to copy array
Disadvantages of Object.clone()
- Object.clone() supports only shallow cloning, To support deep cloning we need to customize our overridden clone method
- To support cloning we need to make sure all our classes hierarchy need to override clone() method
- We don’t have any control over object construction because Object.clone() doesn’t invoke any constructor
- It is not possible to have specific properties exclusions in the cloning
How many ways we can Make a Deep Copy of an Object in Java
There are multiple ways we could use for copying of objects
- copy constructor
- factory methods
- external libraries
- java cloning
Every approach has their own advantages and disadvantages, based on the business need we have to go for what ever feasible for our requirement.
.