ProgrammingJava Developer

Explain the difference between shallow copy and deep copy of objects in Java. How can they be implemented, and in what situations is it important to understand this difference?

Pass interviews with Hintsage AI assistant

Answer.

In Java, shallow copy is the copying of an object where only references to nested objects are copied, not the actual objects themselves. Therefore, changes to the nested objects will be reflected in both the copy and the original. Deep copy implies creating new independent copies of all nested objects.

Example of shallow copy (via clone)

class Address implements Cloneable { String city; Address(String city) { this.city = city; } protected Object clone() throws CloneNotSupportedException { return super.clone(); } } 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(); } } // Usage Person p1 = new Person("Ivan", new Address("Moscow")); Person p2 = (Person) p1.clone(); p2.address.city = "Petersburg"; System.out.println(p1.address.city); // Prints "Petersburg" — shallow copy

Example of deep copy

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(); return cloned; } }

Deep copying creates a completely independent copy of the object.

Trick question.

Question: Can the clone() method be used for guaranteed deep copying of any complex object?

Answer: No, the standard clone() only performs shallow copying. For deep copying, it is necessary to override clone() in all nested classes and explicitly clone all reference fields. Also, many collections and standard classes do not support deep cloning.

Examples of real errors due to lack of understanding of the nuances of the topic.


Story

A collection of users and their addresses was cloned using the clone() method without deep copying. After changing the address of one user, the address of another changed too, because only the reference was copied. Data "leaked" between users.


Story

During serialization of a complex object with nested collections, clone() was used instead of deep copy. After recovery from serialization, the data became inconsistent and NPE occurred.


Story

In the REST API, DTO objects were cloned by default using BeanUtils.copyProperties(), which led to sharing the same collection between clients. As a result, the user could see and edit someone else's data.