Backend Development 4 min read

Understanding Shallow vs Deep Copy in Java: A Practical Cloneable Guide

This article explains the differences between shallow and deep copying in Java, illustrates how the Cloneable interface and the clone() method work, provides complete code examples for both copy types, and clarifies the concept of reference copying with diagrams and test outputs.

Sanyou's Java Diary
Sanyou's Java Diary
Sanyou's Java Diary
Understanding Shallow vs Deep Copy in Java: A Practical Cloneable Guide

Today I share a common Java interview question: Do you understand the difference between deep copy and shallow copy, and what a reference copy is?

Here is the conclusion:

Shallow Copy : Creates a new object on the heap, but if the original object's fields are reference types, the shallow copy copies the reference addresses, so the new and original objects share the same internal objects.

Deep Copy : Completely duplicates the entire object, including all internal objects, so the new object has its own copies of the internal objects.

Now let's look at a concrete example.

Shallow Copy

The shallow copy example implements the Cloneable interface and overrides the clone() method. The clone() method simply calls the superclass Object 's clone() method.

<code>public class Address implements Cloneable {
    private final String name;
    // constructors, getters, setters omitted
    @Override
    public Address clone() {
        try {
            return (Address) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}

public class Person implements Cloneable {
    private Address address;
    // constructors, getters, setters omitted
    @Override
    public Person clone() {
        try {
            Person person = (Person) super.clone();
            return person;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}
</code>

Test:

<code>Person person1 = new Person(new Address("Wuhan"));
Person person1Copy = person1.clone();
// true
System.out.println(person1.getAddress() == person1Copy.getAddress());
</code>

The output shows that the cloned person1 and the original share the same Address instance.

Deep Copy

To achieve deep copy, we modify the Person class's clone() method to also clone the internal Address object.

<code>@Override
public Person clone() {
    try {
        Person person = (Person) super.clone();
        person.setAddress(person.getAddress().clone());
        return person;
    } catch (CloneNotSupportedException e) {
        throw new AssertionError();
    }
}
</code>

Test:

<code>Person person1 = new Person(new Address("Wuhan"));
Person person1Copy = person1.clone();
// false
System.out.println(person1.getAddress() == person1Copy.getAddress());
</code>

The output shows that the cloned person1 now has a different Address instance, confirming a deep copy.

Reference Copy

A reference copy simply means two different references point to the same object.

I also drew a diagram to illustrate shallow copy, deep copy, and reference copy:

JavaDeepCopyShallowCopyCloneableObjectCloningReferenceCopy
Sanyou's Java Diary
Written by

Sanyou's Java Diary

Passionate about technology, though not great at solving problems; eager to share, never tire of learning!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.