When we make a deep copy of an object in Java, that means it will be copied along with the objects to which it refers.
Let’s say we have an object (obj1) that contains references to the other two objects. By its deep cloning, we will get a new object (obj2) whose references will point to two completely new objects of the same type.
We can perform a deep copy using the clone() method from the Object class and implement the Cloneable interface, similar to what we did in shallow object cloning.
Example of Deep Copy in Java
Let’s create two classes (ClassA and ClassC) that implement the Cloneable interface and override the clone() method. ClassA will have a reference to ClassC.
class ClassA implements Cloneable { private int someNum; private ClassC nestedObjectReference; @Override public Object clone() throws CloneNotSupportedException { ClassA classA = (ClassA) super.clone(); // with this, we are ensuring that deep copy will be performed classA.setNestedObjectReference((ClassC) this.nestedObjectReference.clone()); return classA; } // constructor, getters and setters } class ClassC implements Cloneable { private String classData; public ClassC() { } @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } // constructor, getters and setters }
Here, both classes implement the Cloneable interface and override the clone() method from the Object class. Just in ClassA, we added more logic to ensure that deep copy will be performed.
Now let’s test this:
public class Test { public static void main(String[] args) throws CloneNotSupportedException { ClassA obj1 = new ClassA(); obj1.setSomeNum(5); obj1.setNestedObjectReference(new ClassC("one")); ClassA obj2 = (ClassA) obj1.clone(); System.out.println("Object 1 ..."); System.out.println(obj1.getSomeNum()); System.out.println(obj1.getNestedObjectReference().getClassData()); System.out.println("Object 2 ..."); System.out.println(obj2.getSomeNum()); System.out.println(obj2.getNestedObjectReference().getClassData()); // now change the value of the nestedObjectReference using obj2 obj2.getNestedObjectReference().setClassData("two"); System.out.println(); System.out.println(obj1.getNestedObjectReference().getClassData()); System.out.println(obj2.getNestedObjectReference().getClassData()); } }
Advantages of Deep Copy
- The nested objects will be copied too. After the cloning, both objects will have references to different objects, and with that, if we modify a field in one object, that will not be reflected in the other.
- There are some additional libraries that we can use to perform a deep copy, so we don’t need to use the clone() method.
Note: Performing a deep copy can be tricky to implement when working with complex objects, and memory consumption can also be an issue.
That’s it!