← Назад к вопросам

Что такое глубокое копирование?

2.3 Middle🔥 151 комментариев
#ООП

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Глубокое копирование

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

Различие между поверхностным и глубоким копированием

class Person {
    String name;
    Address address;
    
    // Поверхностное копирование
    public Person shallowCopy() {
        Person copy = new Person();
        copy.name = this.name;  // копируем ссылку на String
        copy.address = this.address;  // копируем ссылку на Address
        return copy;
    }
    
    // Глубокое копирование
    public Person deepCopy() {
        Person copy = new Person();
        copy.name = new String(this.name);
        copy.address = new Address(this.address.street, this.address.city);
        return copy;
    }
}

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

Проблемы с поверхностным копированием

При поверхностном копировании обе копии указывают на один и тот же объект Address. Если изменить адрес в копии, это повлияет на оригинальный объект:

Person original = new Person();
original.name = "Иван";
original.address = new Address("Пушкина", "Москва");

Person shallow = original.shallowCopy();
shallow.address.city = "Санкт-Петербург";  // изменит город у original!

Способы реализации глубокого копирования

1. Ручная реализация

Самый простой способ — вручную скопировать все поля:

public Person deepCopy() {
    Person copy = new Person();
    copy.name = new String(this.name);
    copy.address = new Address(this.address.street, this.address.city);
    return copy;
}

2. Использование Cloneable интерфейса

class Person implements Cloneable {
    String name;
    Address address;
    
    @Override
    public Object clone() throws CloneNotSupportedException {
        Person copy = (Person) super.clone();
        copy.address = (Address) address.clone();
        return copy;
    }
}

class Address implements Cloneable {
    String street;
    String city;
    
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

3. Сериализация и десериализация

public Person deepCopy() throws IOException, ClassNotFoundException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(this);
    oos.close();
    
    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
    ObjectInputStream ois = new ObjectInputStream(bais);
    Person copy = (Person) ois.readObject();
    ois.close();
    
    return copy;
}

4. Использование библиотек

// Apache Commons Lang
Person copy = SerializationUtils.clone(original);

// Google Gson
Gson gson = new Gson();
Person copy = gson.fromJson(gson.toJson(original), Person.class);

Когда использовать глубокое копирование

  • Когда нужна полная независимость копии от оригинала
  • При работе с изменяемыми объектами внутри объекта
  • В многопоточных приложениях, где разные потоки работают с копиями
  • При реализации паттерна Prototype

Сложность и производительность

Глубокое копирование дороже поверхностного по памяти и CPU. Для больших объектов может быть узким местом.

Вывод: глубокое копирование необходимо, когда нужна полная независимость объектов с их внутренним состоянием.