How would you implement a deep copy in Java?

A deep copy creates a completely independent duplicate of an object, including all nested objects it references. Unlike a shallow copy, where referenced objects are shared, a deep copy recursively creates new instances of all dependent objects. As a result, changes made to the copied object do not affect the original object.

Key Points: • Deep copying duplicates both the parent object and all referenced child objects. • It prevents unintended side effects caused by shared object references. • Common approaches include copy constructors, custom clone() implementations, or serialization-based copying.

Example: Consider an Employee object containing an Address object. In a deep copy, both Employee and Address are copied into new instances. Modifying the copied employee's address will not impact the original employee's address.

Code Example:

class Address {

    private String city;

    public Address(String city) {
        this.city = city;
    }

    public Address(Address address) {
        this.city = address.city;
    }
}

class Employee {

    private String name;
    private Address address;

    public Employee(

String name,

            Address address) {

        this.name = name;
        this.address = address;
    }

    // Deep Copy Constructor
    public Employee(Employee employee) {

        this.name = employee.name;
        this.address =
                new Address(employee.address);
    }
}

public class DeepCopyDemo {

    public static void main(String[] args) {

        Employee emp1 =
                new Employee(
                        "John",
                        new Address("Pune"));

        Employee emp2 =
                new Employee(emp1);

        System.out.println(
                "Deep Copy Created");
    }
}

Interview Tip: A concise interview answer is: A deep copy creates a completely independent copy of an object along with all its nested objects. It ensures that no references are shared between the original and copied objects, preventing changes in one object from affecting the other. Common implementations include copy constructors, custom cloning, and serialization.