Java.Core.What is the difference between shallow copy and deep copy in Java?

Let’s break down the difference between shallow copy and deep copy in Java — this is a classic interview topic, especially for cloning objects.


🌐 What is a Shallow Copy?

A shallow copy copies only the top-level structure of an object.

  • It copies references to nested objects instead of copying the nested objects themselves.
  • Both the original and the copied object share the same nested (inner) objects.

Example — Shallow Copy

class Address {
    String city;

    public Address(String city) {
        this.city = city;
    }
}

class Person implements Cloneable {
    String name;
    Address address;

    public Person(String name, Address address) {
        this.name = name;
        this.address = address;
    }

    @Override
    protected Person clone() throws CloneNotSupportedException {
        return (Person) super.clone();  // Shallow copy
    }
}

Usage

Person p1 = new Person("Alice", new Address("New York"));
Person p2 = p1.clone();

p2.name = "Bob";
p2.address.city = "Los Angeles";  // Changes reflected in both!

System.out.println(p1.address.city);  // "Los Angeles" — both share same address

🔎 Summary of Shallow Copy

PropertyExplanation
Top-level fields (primitives)Copied directly
Reference fields (objects)References are copied (both objects share the same inner objects)
SpeedFaster (no need to copy everything deeply)
When to useObjects where sharing inner objects is fine (e.g., cache)

🌊 What is a Deep Copy?

A deep copy copies the top-level object and all nested objects recursively.

  • The original and copy are completely independent.
  • Changes to inner objects in the copy do not affect the original.

Example — Deep Copy

class Address {
    String city;

    public Address(String city) {
        this.city = city;
    }

    public Address(Address other) {
        this.city = other.city;  // Copy inner field
    }
}

class Person implements Cloneable {
    String name;
    Address address;

    public Person(String name, Address address) {
        this.name = name;
        this.address = address;
    }

    @Override
    protected Person clone() {
        return new Person(this.name, new Address(this.address));  // Deep copy
    }
}

Usage

Person p1 = new Person("Alice", new Address("New York"));
Person p2 = p1.clone();

p2.name = "Bob";
p2.address.city = "Los Angeles";  // Changes to p2 do NOT affect p1

System.out.println(p1.address.city);  // "New York"

📊 Summary of Deep Copy

PropertyExplanation
Top-level fields (primitives)Copied directly
Reference fields (objects)New copies are created (full copy)
SpeedSlower (copies everything)
When to useFor truly independent copies (e.g., working on data snapshots)

🔥 Key Differences Summary Table

FeatureShallow CopyDeep Copy
Copies top-level fields?✅ Yes✅ Yes
Copies nested objects?❌ No (shared)✅ Yes (new objects)
Performance🚀 Fast🐢 Slower
Independence❌ Linked (modifying inner objects affects both)✅ Fully independent
Typical Use CaseWhen nested objects are immutableWhen nested objects are mutable and need full separation

⚠️ Important Note — Object.clone()

  • By default, clone() in Java does shallow copying.
  • If you want deep copying, you have to override clone() and explicitly copy inner objects.

📣 Quick Interview Pro Tip

✅ When asked, say:

“Shallow copy only copies the outer object — inner objects are shared. Deep copy copies everything, including deep nested objects, creating a completely independent object graph.”

✅ Mention:

  • clone() does shallow copy by default.
  • To make a deep copy, you have to manually copy all nested objects.

💡 Bonus Trick

If the object is Serializable, you can do deep copy using serialization like this:

// Deep copy via serialization (useful for large objects with many fields)
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(original);

ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
Object copy = ois.readObject();  // Fully independent deep copy
This entry was posted in Без рубрики. Bookmark the permalink.