In Java, when you clone or copy an object, you may expect the new object to be completely independent of the original one. But that’s not always the case. Depending on how you copy an object, changes in one can affect the other — or not.
This brings us to two important concepts in Java object copying: Shallow Copy and Deep Copy. Although they sound similar, their behavior is very different.
📘 What is Shallow Copy?
A shallow copy is a copy of an object where:
- The new object has copies of primitive fields.
- The references to objects inside it are shared between the original and the cloned object.
This means the cloned and original objects are not 100% independent — they share inner objects.
✅ Characteristics of Shallow Copy

Shallow Copy Example
class Address {
String city;
Address(String city) {
this.city = city;
}
}
class Person implements Cloneable {
String name;
Address address;
Person(String name, Address address) {
this.name = name;
this.address = address;
}
protected Object clone() throws CloneNotSupportedException {
return super.clone(); // Shallow copy
}
}
public class ShallowCopyDemo {
public static void main(String[] args) throws CloneNotSupportedException {
Address addr = new Address("Delhi");
Person p1 = new Person("Amit", addr);
Person p2 = (Person) p1.clone();
p2.name = "Ravi";
p2.address.city = "Mumbai"; // shared object
System.out.println(p1.name + " - " + p1.address.city); // Amit - Mumbai
System.out.println(p2.name + " - " + p2.address.city); // Ravi - Mumbai
}
}
🔍 What Happened?
p2
is a clone ofp1
, but both share the sameAddress
object.- Changing the
city
ofp2.address
also affectsp1.address
. - That’s a classic case of shallow copy.
📘 What is Deep Copy?
A deep copy is a copy of an object where:
- A new object is created along with new copies of all referenced objects.
- The cloned object and original object are 100% disjoint — no shared references.
- This ensures complete independence between the two objects.
✅ Characteristics of Deep Copy

Deep Copy Example
class Address implements Cloneable {
String city;
Address(String city) {
this.city = city;
}
protected Object clone() throws CloneNotSupportedException {
return new Address(this.city);
}
}
class Person implements Cloneable {
String name;
Address address;
Person(String name, Address address) {
this.name = name;
this.address = address;
}
protected Object clone() throws CloneNotSupportedException {
Person cloned = (Person) super.clone();
cloned.address = (Address) address.clone(); // deep copy of reference
return cloned;
}
}
public class DeepCopyDemo {
public static void main(String[] args) throws CloneNotSupportedException {
Address addr = new Address("Delhi");
Person p1 = new Person("Amit", addr);
Person p2 = (Person) p1.clone();
p2.name = "Ravi";
p2.address.city = "Mumbai"; // cloned address
System.out.println(p1.name + " - " + p1.address.city); // Amit - Delhi
System.out.println(p2.name + " - " + p2.address.city); // Ravi - Mumbai
}
}
🔍 What Happened?
- We manually cloned the
Address
object inside the overriddenclone()
method. - Now
p1
andp2
have differentAddress
instances. - Changes to one don’t affect the other — this is deep copying.
🔁 Shallow Copy vs Deep Copy — Comparison Table

When to Use Shallow Copy
You can use shallow copy when:
- The class only contains primitive data types or immutable objects (e.g.,
String
). - You do not intend to modify the referenced objects after cloning.
- Performance is more important than data isolation.
When to Use Deep Copy
Use deep copy when:
- The object contains references to other mutable objects (like lists, maps, or custom objects).
- You want complete isolation between the original and the cloned object.
- Data integrity and independence are critical to your application.
📌 Final Thoughts
Understanding the difference between shallow copy and deep copy is crucial for writing bug-free and memory-safe Java code, especially in large applications where objects reference other objects.
- Use shallow copy when your class is simple and doesn’t hold complex nested objects.
- Use a deep copy when you want full separation between the original and cloned data.
Also, always test cloning in real scenarios to avoid unexpected behaviors caused by shared references.
Comments
Post a Comment
Leave Comment