Ответ
Поверхностное копирование (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) ссылочные поля, и вы хотите обеспечить полную независимость копии.