Skip to main content

Shallow Copy vs. Deep Copy

Easy

Interview Question: "Can you explain the difference between a shallow copy and a deep copy? If I modify a nested object in a shallow copy, what happens to the original, and how do you handle circular references during deep copies?"

Picture a briefcase holding a gold coin and a slip of paper with a house's address written on it.

  • Shallow copy: you get a new briefcase, and a freshly minted coin inside it - but the address slip is just copied word for word. Both briefcases now point to the same house. Repaint that house, and whoever opens either briefcase sees the new paint.
  • Deep copy: you get a new briefcase, a new coin, and - instead of copying the address - a whole new house is built from scratch on a different street, and that new address goes in the slip. The two houses have nothing to do with each other anymore.

That's the whole idea. A shallow copy duplicates the outer object but still points at the same nested objects as the original. A deep copy duplicates the outer object and recursively rebuilds every nested object too, so the copy and the original share nothing.

SHALLOW COPY (SHARED NESTED OBJECT)originalshallowCopyAddress Object0x100 (same memory)Shared memory reference: mutating fields through either copy affects bothDEEP COPY (INDEPENDENT NESTED OBJECTS)originalAddress (0x100)deepCopyAddress (0x200)Completely isolatedIndependent allocations
A shallow copy duplicates the outer object, but inner references still point to the same instance. A deep copy recursively duplicates every nested object.

Comparing the two​

DimensionShallow CopyDeep Copy
Outer ContainerA new object is allocated.A new object is allocated.
Nested ObjectsShared - both point at the same memory.Independent - each one is freshly cloned.
Mutation RiskChanging a nested field also changes the original.Changing a nested field never touches the original.
PerformanceFast, O(1), barely any extra memory.Slower - has to walk the whole object graph and allocate as it goes.

The trap: objects that reference each other​

If you're asked to write deepCopy() by hand, watch out for cycles: Object A points at Object B, and Object B points right back at A. A naive recursive copy bounces between them forever and blows the stack with a StackOverflowError.

The fix is to remember what you've already copied. Keep a map from each original object's identity to its already-made clone (Java's IdentityHashMap, or a dict keyed by id() in Python). Before cloning a reference, check that map first - if it's already there, reuse the clone instead of recursing again.


Clean Code Example​

Here is how shallow and deep copies are implemented across languages:

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

class User {
String name;
Address address;

// Shallow Copy Constructor: Shares Address reference
User(User other, boolean isDeep) {
this.name = other.name;
if (isDeep) {
// DEEP COPY: Allocates a new Address object
this.address = new Address(other.address.city);
} else {
// SHALLOW COPY: Shares the same Address pointer
this.address = other.address;
}
}
}