В чем разница между поверхностным и глубоким клонированием объектов в Java?

«В чем разница между поверхностным и глубоким клонированием объектов в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Поверхностное копирование (Shallow Copy) создает новый объект, но копирует значения всех полей "как есть". Для полей-примитивов копируется значение, для полей-ссылок копируется сама ссылка (адрес памяти). В результате оба объекта начинают ссылаться на одни и те же вложенные объекты.

Глубокое копирование (Deep Copy) создает новый объект и рекурсивно создает копии всех объектов, на которые ссылаются его поля. В итоге получается полностью независимая копия всего графа объектов.

Пример, иллюстрирующий разницу:

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

class Person implements Cloneable {
    String name;
    Address address;

    // Поверхностное клонирование (стандартная реализация)
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone(); // address будет скопирована как ссылка
    }

    // Глубокое клонирование (пользовательская реализация)
    public Person deepCopy() {
        Person copy = new Person();
        copy.name = this.name;
        copy.address = new Address(this.address.city); // Создаем новый объект Address
        return copy;
    }
}

// Использование
Person original = new Person("Alice", new Address("Moscow"));
Person shallowCopy = (Person) original.clone();
Person deepCopy = original.deepCopy();

original.address.city = "SPb";
// shallowCopy.address.city теперь тоже "SPb" (общая ссылка)!
// deepCopy.address.city останется "Moscow" (независимая копия).

Когда что использовать:

  • Поверхностное копирование подходит для объектов, содержащих только примитивы или неизменяемые (immutable) ссылочные поля.
  • Глубокое копирование необходимо, если объект содержит изменяемые (mutable) ссылочные поля, и вы хотите обеспечить полную независимость копии.