When working with objects in Java or Python, one of the most confusing concepts is the difference between shallow copy and deep copy. Both languages pass references to objects around, which means if you’re not careful, your "copies" may not be as independent as you think.
In this article, we’ll break down the differences with clear examples in Java and Python.
🔹 What is Shallow Copy?
A shallow copy creates a new object, but it only copies the top-level structure.
If the object contains other objects (lists, maps, custom objects), those are not cloned — both copies still point to the same nested objects.
👉 Modifying a nested object in one copy will affect the other.
✅ Shallow Copy in Java
import java.util.*;
class Person implements Cloneable {
String name;
List<String> hobbies;
Person(String name, List<String> hobbies) {
this.name = name;
this.hobbies = hobbies;
}
// Shallow copy
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
List<String> hobbies = new ArrayList<>(Arrays.asList("Cricket", "Chess"));
Person p1 = new Person("John", hobbies);
Person p2 = (Person) p1.clone(); // shallow copy
p2.hobbies.add("Football");
System.out.println("p1 hobbies: " + p1.hobbies);
System.out.println("p2 hobbies: " + p2.hobbies);
}
}
Output:
p1 hobbies: [Cricket, Chess, Football]
p2 hobbies: [Cricket, Chess, Football]
Both objects share the same list reference.
✅ Shallow Copy in Python
import copy
p1 = {"name": "John", "hobbies": ["Cricket", "Chess"]}
p2 = copy.copy(p1) # shallow copy
p2["hobbies"].append("Football")
print("p1 hobbies:", p1["hobbies"])
print("p2 hobbies:", p2["hobbies"])
Output:
p1 hobbies: ['Cricket', 'Chess', 'Football']
p2 hobbies: ['Cricket', 'Chess', 'Football']
Same behavior as Java — shallow copy still shares the inner list.
🔹 What is Deep Copy?
A deep copy duplicates not just the object itself, but also all objects it references.
The copy is completely independent — modifying one does not affect the other.
✅ Deep Copy in Java
import java.util.*;
class Person implements Cloneable {
String name;
List<String> hobbies;
Person(String name, List<String> hobbies) {
this.name = name;
this.hobbies = hobbies;
}
// Deep copy
@Override
protected Object clone() throws CloneNotSupportedException {
Person cloned = (Person) super.clone();
cloned.hobbies = new ArrayList<>(this.hobbies); // copy list separately
return cloned;
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
List<String> hobbies = new ArrayList<>(Arrays.asList("Cricket", "Chess"));
Person p1 = new Person("John", hobbies);
Person p2 = (Person) p1.clone(); // deep copy
p2.hobbies.add("Football");
System.out.println("p1 hobbies: " + p1.hobbies);
System.out.println("p2 hobbies: " + p2.hobbies);
}
}
Output:
p1 hobbies: [Cricket, Chess]
p2 hobbies: [Cricket, Chess, Football]
Now the lists are independent.
✅ Deep Copy in Python
import copy
p1 = {"name": "John", "hobbies": ["Cricket", "Chess"]}
p2 = copy.deepcopy(p1) # deep copy
p2["hobbies"].append("Football")
print("p1 hobbies:", p1["hobbies"])
print("p2 hobbies:", p2["hobbies"])
Output:
p1 hobbies: ['Cricket', 'Chess']
p2 hobbies: ['Cricket', 'Chess', 'Football']
Here too, the inner list is copied independently.
🔹 Shallow vs Deep Copy — Quick Comparison
Feature | Shallow Copy 🟡 | Deep Copy 🟢 |
---|---|---|
Copies the object itself? | ✅ Yes | ✅ Yes |
Copies nested objects? | ❌ No (shared) | ✅ Yes |
Nested object modification affects original? | ✅ Yes | ❌ No |
Example in Java | super.clone() |
new ArrayList<>(field) |
Example in Python | copy.copy() |
copy.deepcopy() |
🔹 Real-Life Analogy
- Shallow Copy: You photocopy a report, but both copies reference the same external appendix file. If someone edits the appendix, both reports are affected.
- Deep Copy: You photocopy the report and also duplicate the appendix. Each report is fully independent.
🔹 Key Takeaways
- In Java,
super.clone()
→ shallow copy; you must clone mutable fields manually for deep copy. - In Python,
copy.copy()
→ shallow copy;copy.deepcopy()
→ deep copy. - If your objects contain only immutable data (like integers, strings), shallow copy is often enough.
- If your objects contain mutable data structures (lists, dicts, maps), you usually want a deep copy.
Top comments (0)