Understanding Shallow Copy vs Deep Copy in Java

Answered using GPT-4o-mini by Java Q&A Hub

Question:

What are shallow copy and deep copy in Java?

Answer:

In Java, the concepts of shallow copy and deep copy refer to the ways in which objects can be duplicated. Understanding these concepts is important for managing object references and ensuring that changes to one object do not unintentionally affect another.

Shallow Copy

A shallow copy of an object creates a new object, but it does not create copies of the objects that are referenced by the original object. Instead, it copies the references to those objects. This means that if the original object contains references to mutable objects, changes made to those mutable objects through one reference will be reflected in the other reference.

Example of Shallow Copy

class Address {
    String city;

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

class Person {
    String name;
    Address address;

    Person(String name, Address address) {
        this.name = name;
        this.address = address;
    }
}

public class ShallowCopyExample {
    public static void main(String[] args) {
        Address address = new Address("New York");
        Person person1 = new Person("Alice", address);

        // Creating a shallow copy
        Person person2 = new Person(person1.name, person1.address);

        // Modifying the address of person2
        person2.address.city = "Los Angeles";

        // Both person1 and person2 refer to the same Address object
        System.out.println(person1.address.city); // Output: Los Angeles
        System.out.println(person2.address.city); // Output: Los Angeles
    }
}

Deep Copy

A deep copy, on the other hand, creates a new object and also recursively creates copies of all objects referenced by the original object. This means that the new object and the original object are completely independent of each other. Changes made to the mutable objects in one copy will not affect the other copy.

Example of Deep Copy

class Address {
    String city;

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

    // Method to create a deep copy of Address
    Address deepCopy() {
        return new Address(this.city);
    }
}

class Person {
    String name;
    Address address;

    Person(String name, Address address) {
        this.name = name;
        this.address = address;
    }

    // Method to create a deep copy of Person
    Person deepCopy() {
        return new Person(this.name, this.address.deepCopy());
    }
}

public class DeepCopyExample {
    public static void main(String[] args) {
        Address address = new Address("New York");
        Person person1 = new Person("Alice", address);

        // Creating a deep copy
        Person person2 = person1.deepCopy();

        // Modifying the address of person2
        person2.address.city = "Los Angeles";

        // person1's address remains unchanged
        System.out.println(person1.address.city); // Output: New York
        System.out.println(person2.address.city); // Output: Los Angeles
    }
}

Summary

  • Shallow Copy: Copies the object and its references. Changes to mutable objects affect both copies.
  • Deep Copy: Copies the object and all objects it references, creating independent copies. Changes to mutable objects do not affect the other copy.

In Java, you can implement deep copying manually by defining methods to clone or copy objects, as shown in the examples above. Alternatively, you can use serialization techniques to achieve deep copying, but this approach has its own complexities and performance considerations.