Cloning in Java — Shallow vs Deep vs Lazy Copy, and a small hack to clone Java Objects

Ganesh Raj Padhayay
3 min readJan 18, 2020

--

We will be discussing the following topics in this blog :

  1. What is Cloning? Copy Constructor & Assignment Operator
  2. clone() method, Shallow, Deep Copy, and Lazy Copy
  3. Cloning using Serialization(hack to avoid nested deep copy)

Let’s discuss these topics in details:

What is Cloning? Copy Constructor & Assignment Operator

Cloning is creating a copy of the original object. We can use the assignment operator (=) or copy constructor to achieve this.

Copy Constructor provides a deep copy of the object whereas the assignment operator provides us with a shallow copy of the original object, we will explore this in detail in upcoming sections.

Please refer to the code below:

simple cloning explained using copy constructors

clone() method, Shallow, Deep Copy, and Lazy Copy

We all know that Object is the parent class of all the classes in Java and the clone() method of this class whenever invoked, JVM does the following things:

  1. If the class has only primitive data type members then a completely new copy of the object will be created and the reference to the new object copy will be returned.
  2. If the class contains members of any class type then only the object references to those members are copied and hence the member references in both the original object as well as the cloned object refer to the same object.

Although, we can always override clone() as per our implementation.

In this example, we will see that when we only have primitive data types with us the clone() method by default will give a different cloned object.

Is not the output self-explanatory?

Let’s try to add a custom Book class in our student object and see what happens keeping everything else fixed.

As we can see, we got the same reference to the book object present in the Student class since we didn’t write the cloning logic inside the clone() method of Student Class.

NOTE: Shallow clone is “default implementation” in Java. In overridden clone the method, if you are not cloning all the object types (not primitives), then you are making a shallow copy.

To correctly implement this, we will ask the compiler to clone the book object as well in clone() of Student class and for that, clone() of Book also need to be overridden and hence we can achieve the different reference for our complete Student object - this is what we call deep copy because both original and cloned objects can change independently of each other.

As we can see, everything works perfectly here but we can also see that deep copying is a very expensive process as compared to the shallow copy and it is also very cumbersome if we have so many nested classes.

What is the solution to this? Lazy Copy! Nobody can explain it better than Wikipedia itself :P

A lazy copy is a combination of both shallow copy and Deep Copy. When initially copying an object, a (fast) shallow copy is used. A counter is also used to track how many objects share the data. When the program wants to modify an object, it can determine if the data is shared (by examining the counter) and can do a deep copy if necessary. The lazy copy looks to the outside just as a deep copy but takes advantage of the speed of a shallow copy whenever possible. The downsides are rather high but constant base costs because of the counter. Also, in certain situations, circular references can also cause problems.

Cloning using Serialization(hack to avoid nested deep copy)

Serialization is another easy way of deep cloning. In this method, you just serialize the object to be cloned and de-serialize it. Obviously, all the objects which are involved in the cloning process need to be implement Serializable interface, Student and Book in our case.

NOTE: This method has cons more than the pros so please use it at your own risk :P

  1. Serialization is a hugely expensive process. It could easily be a hundred times more expensive than the clone() method.
  2. Second, not all objects are Serializable.

BONUS: Since we use gson library very heavily in almost all types of projects, this method can be used to deep copy objects in Android.

That’s it for now.

Thanks for reading :)

--

--