Mastering Java Deep Copy: Techniques, Code Samples, and Best Practices
This article explains Java deep copy, its differences from shallow copy, key use cases such as data safety and avoiding shared state, and demonstrates three implementation methods—using Cloneable, serialization, and third‑party libraries like Guava—complete with runnable code examples.
What is Deep Copy in Java
Deep copy creates a completely independent copy of an object by recursively duplicating all objects reachable from the original, unlike shallow copy which copies only the top‑level fields.
Why Use Deep Copy
Data isolation : Modifications to the copy do not affect the original, protecting sensitive data.
Thread safety : Each thread can work with its own copy, avoiding shared mutable state.
Complex object graphs : Nested objects, collections, and graphs are fully duplicated.
Testing and backup : Provides reliable clones for experiments, backups, or unit tests.
Common Implementation Techniques
1. Using Cloneable and overriding clone()
Implement Cloneable, call super.clone() for a shallow copy, then manually deep‑copy mutable fields (e.g., collections) by creating new instances.
import java.util.ArrayList;
import java.util.List;
class Person implements Cloneable {
private String name;
private List<String> hobbies;
public Person(String name, List<String> hobbies) {
this.name = name;
this.hobbies = hobbies;
}
public void addHobby(String hobby) {
hobbies.add(hobby);
}
@Override
public Person clone() throws CloneNotSupportedException {
// shallow copy
Person copy = (Person) super.clone();
// deep copy mutable list
copy.hobbies = new ArrayList<>(this.hobbies);
return copy;
}
@Override
public String toString() {
return "Person{name='" + name + "', hobbies=" + hobbies + "}";
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
List<String> hobbies = new ArrayList<>();
hobbies.add("Reading");
hobbies.add("Swimming");
Person p1 = new Person("Alice", hobbies);
Person p2 = p1.clone();
p2.addHobby("Hiking");
System.out.println("p1 = " + p1);
System.out.println("p2 = " + p2);
}
}2. Using Java Serialization
Serializing an object to a byte array and deserializing it creates a new object graph. All classes in the graph must implement java.io.Serializable.
import java.io.*;
class DeepCopyViaSerialization implements Serializable {
public Object deepCopy() throws IOException, ClassNotFoundException {
// Serialize to byte array
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try (ObjectOutputStream out = new ObjectOutputStream(bos)) {
out.writeObject(this);
}
// Deserialize from byte array
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
try (ObjectInputStream in = new ObjectInputStream(bis)) {
return in.readObject();
}
}
}3. Using Third‑Party Libraries
Libraries such as Google Guava provide immutable collection factories that effectively act as deep copies because the returned collections cannot be modified.
import com.google.common.collect.ImmutableList;
public class DeepCopyWithGuava {
public static void main(String[] args) {
// Original immutable list
ImmutableList<String> original = ImmutableList.of("A", "B", "C");
// Deep copy – creates a new immutable instance
ImmutableList<String> copy = ImmutableList.copyOf(original);
// Reassign original reference; copy remains unchanged
original = ImmutableList.of("X", "Y", "Z");
System.out.println("Original: " + original);
System.out.println("Copy: " + copy);
}
}Considerations
Cloneable requires explicit handling of each mutable field; forgetting a field results in a shallow copy.
Serialization can be slower and requires all classes to be serializable; it cannot copy objects that hold transient resources such as open streams.
Third‑party utilities often work only for immutable data structures; mutable objects still need custom cloning.
Architect Chen
Sharing over a decade of architecture experience from Baidu, Alibaba, and Tencent.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
