What is a Deep Copy?
Deep copy explained — recursive object duplication, cyclic references, and copy constructors — with a Java code example and Q&A.
Expected Interview Answer
A deep copy creates a completely independent duplicate of an object, recursively copying every nested object it references as well, so the original and the copy share absolutely no mutable state and changes to one never affect the other.
Unlike a shallow copy, which stops at copying references to nested objects, a deep copy walks the entire object graph and constructs new instances for every reachable reference-type field, all the way down. This is essential when nested objects are mutable and independence is required — for example, cloning a Person whose Address must be editable separately for each copy without cross-contamination. Deep copying is more expensive in both time and memory than shallow copying, and requires careful handling of cycles in the object graph (an object that references itself indirectly) to avoid infinite recursion, typically solved by tracking already-copied objects. In Java, deep copying is commonly implemented via a custom copy constructor, manually cloning each nested field, or serialization-based cloning, since Object.clone() alone only gives shallow semantics.
- Guarantees full independence between original and copy
- Prevents shared-mutation bugs across the entire object graph
- Safe for concurrent or long-lived copies that must diverge independently
- Essential when nested objects are mutable and separately owned
AI Mentor Explanation
Instead of photocopying a scorecard with a sticky note pointing at the shared official ball log, a deep copy means also photocopying that ball log itself and attaching the fresh photocopy to the new scorecard, so scribbling a correction on the copy’s ball log never touches the original’s. That is a deep copy: every referenced record is independently duplicated, not just pointed to.
Step-by-Step Explanation
Step 1
Allocate a new top-level object
Create a new instance of the object being copied, just like a shallow copy would.
Step 2
Recursively copy each reference field
For every field pointing to another object, create a brand-new deep copy of that object too, not just copy the reference.
Step 3
Handle cycles carefully
Track already-copied objects (e.g. via an identity map) to avoid infinite recursion on self-referential graphs.
Step 4
Result is fully independent
The copy shares no mutable state with the original anywhere in the object graph.
What Interviewer Expects
- Correct contrast with shallow copy (recursive vs reference-only duplication)
- Awareness of the performance and memory cost of deep copying
- Knowledge of common implementation strategies (copy constructor, serialization)
- Recognition that cyclic object graphs need special handling to avoid infinite loops
Common Mistakes
- Assuming Object.clone() performs a deep copy by default
- Forgetting to handle cyclic references, causing a StackOverflowError
- Deep-copying immutable fields unnecessarily, wasting memory and time
- Only copying the first level of nesting and calling it a deep copy
Best Answer (HR Friendly)
“A deep copy creates a completely separate version of an object and everything it references, so the copy and the original never share any mutable data anywhere in the object graph. It costs more time and memory than a shallow copy because every nested object has to be duplicated too, but it is the right choice whenever the copy needs to be safely and independently editable.”
Code Example
class Address {
String city;
Address(String city) { this.city = city; }
Address(Address other) { this.city = other.city; } // copy constructor
}
class Person {
String name;
Address address;
Person(String name, Address address) {
this.name = name;
this.address = address;
}
// Deep copy constructor: rebuilds the nested Address independently
Person(Person other) {
this.name = other.name;
this.address = new Address(other.address);
}
}
Person original = new Person("Asha", new Address("Pune"));
Person deepCopy = new Person(original);
deepCopy.address.city = "Mumbai";
System.out.println(original.address.city); // still prints "Pune" - fully independentFollow-up Questions
- How does a deep copy differ from a shallow copy in what gets duplicated?
- How do you handle cyclic references when implementing a deep copy?
- What are the common ways to implement deep copying in Java?
- What is the performance tradeoff of choosing deep copy over shallow copy?
MCQ Practice
1. A deep copy differs from a shallow copy by?
A deep copy recursively rebuilds every nested object, unlike a shallow copy which shares references.
2. What problem must a correct deep-copy implementation guard against?
Cyclic references between objects can cause infinite recursion unless already-copied objects are tracked.
3. Does Object.clone() in Java perform a deep copy by default?
Object.clone() defaults to shallow copy semantics; deep copying must be implemented manually.
Flash Cards
Deep copy in one line? — A fully independent duplicate, recursively copying every nested object in the graph.
Main cost of deep copy? — More time and memory than a shallow copy, since every nested object is duplicated.
What must a deep copy guard against? — Infinite recursion from cyclic references — track already-copied objects.
Common deep-copy implementation in Java? — A manual copy constructor that recursively duplicates each nested field.