Understanding Shallow Copy vs Deep Copy in Java

Java Q&A Hub 使用 GPT-4o-mini 回答

问题:

What are shallow copy and deep copy in Java?

回答:

In Java, the concepts of shallow copy and deep copy refer to two different ways of copying objects. Understanding these concepts is important for managing object references and ensuring that your program behaves as expected when dealing with mutable objects.

Shallow Copy

A shallow copy of an object is a new object that is a copy of the original object, but it only copies the references to the objects contained within the original object. This means that if the original object contains references to other objects, the shallow copy will reference the same objects rather than creating new copies of them.

In Java, you can create a shallow copy using the clone() method (if the class implements the Cloneable interface) or by using a copy constructor. Here's an example:

class Person implements Cloneable {
    String name;
    Address address; // Assume Address is another class

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

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone(); // This creates a shallow copy
    }
}

class Address {
    String city;

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

// Usage
Person original = new Person("John", new Address("New York"));
Person shallowCopy = (Person) original.clone();

In this example, shallowCopy.address will point to the same Address object as original.address. If you modify the Address object through either original or shallowCopy, the changes will be reflected in both.

Deep Copy

A deep copy, on the other hand, creates a new object and recursively copies all objects referenced by the original object. This means that the deep copy will have its own copies of all objects, and changes to the deep copy will not affect the original object and vice versa.

To create a deep copy, you typically need to implement a custom method that explicitly copies all mutable objects. Here's an example:

class Person implements Cloneable {
    String name;
    Address address;

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

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person cloned = (Person) super.clone();
        cloned.address = new Address(this.address.city); // Create a new Address object
        return cloned;
    }
}

// Usage
Person original = new Person("John", new Address("New York"));
Person deepCopy = (Person) original.clone();

In this example, deepCopy.address is a new Address object, so changes to deepCopy.address will not affect original.address.

Summary

  • Shallow Copy: Copies the object and its references. Changes to mutable objects referenced by the original will affect the shallow copy.
  • Deep Copy: Copies the object and all objects it references, creating entirely new instances. Changes to mutable objects in the deep copy do not affect the original.

When deciding between shallow and deep copies, consider the mutability of the objects involved and the desired behavior of your application.