Ответ
Глубокое копирование создает новый объект и рекурсивно копирует все поля, включая вложенные объекты, а не просто копирует ссылки на них.
Основные подходы:
-
Ручная реализация (через конструктор копирования или
clone()):public class Person { private String name; private Address address; // mutable объект // Конструктор глубокого копирования public Person(Person original) { this.name = original.name; this.address = new Address(original.address); // Копируем вложенный объект } // Или через переопределение clone() (менее предпочтительно) @Override protected Person clone() throws CloneNotSupportedException { Person cloned = (Person) super.clone(); cloned.address = this.address.clone(); // Требует, чтобы Address тоже реализовывал Cloneable return cloned; } } -
Сериализация/десериализация:
import java.io.*; public static <T extends Serializable> T deepCopy(T object) throws IOException, ClassNotFoundException { ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(byteOut); out.writeObject(object); out.flush(); ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray()); ObjectInputStream in = new ObjectInputStream(byteIn); return (T) in.readObject(); }- Плюсы: Универсально для любых графов объектов.
- Минусы: Низкая производительность; все объекты в графе должны реализовывать
Serializable.
-
Использование библиотек (рекомендуется для сложных объектов):
- Apache Commons Lang:
SerializationUtils.clone(object)(требуетSerializable). - Jackson/Gson: Сериализация в JSON и обратная десериализация.
// Пример с Gson Gson gson = new Gson(); Person copy = gson.fromJson(gson.toJson(original), Person.class);
- Apache Commons Lang:
Выбор метода зависит от сложности объекта, требований к производительности и необходимости сериализуемости.