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

Что нужно сделать чтобы реализовать неглубокое копирование?

1.0 Junior🔥 131 комментариев
#Основы Java

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

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

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

# Неглубокое копирование в Java

Неглубокое копирование (shallow copy) создаёт новый объект, но внутренние ссылки указывают на те же объекты, что и оригинал. Это отличается от глубокого копирования, где копируются и вложенные объекты.

Способы реализации

1. Переопределение метода clone() с интерфейсом Cloneable

Самый распространённый подход — реализовать интерфейс Cloneable и переопределить метод clone():

public class Person implements Cloneable {
    private String name;
    private int age;
    private Address address; // вложенный объект
    
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone(); // неглубокое копирование
    }
}

Person original = new Person("John", 30, new Address("Moscow"));
Person copy = (Person) original.clone();

// copy.address указывает на ТОТ ЖЕ объект Address, что и original.address
copy.address.setCity("SPB"); // это изменит и original.address

2. Копирование в конструкторе

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

public class Person {
    private String name;
    private int age;
    private Address address;
    
    public Person(Person other) {
        this.name = other.name;        // копируем примитивы
        this.age = other.age;
        this.address = other.address;  // копируем ссылку на ОДИН объект
    }
}

Person original = new Person("John", 30, new Address("Moscow"));
Person copy = new Person(original);

// copy.address и original.address — это один объект

3. Использование метода copyOf() из Collections (для коллекций)

Для поверхностного копирования коллекций:

List<String> original = List.of("Java", "Spring", "Hibernate");
List<String> copy = new ArrayList<>(original);

// Теперь это разные коллекции, но содержат ссылки на одни и те же строки
// Для строк это не проблема (immutable), но для объектов:

List<Person> people = List.of(
    new Person("John"),
    new Person("Jane")
);
List<Person> peopleCopy = new ArrayList<>(people);

peopleCopy.get(0).setName("Bob"); // изменит и оригинальный список

Ключевые особенности

  1. Примитивные типы: int, long, boolean и т.д. копируются по значению
  2. Объекты: копируются по ссылке — новый объект содержит ссылку на старый
  3. Коллекции: сама коллекция копируется, но элементы остаются теми же

Пример различия shallow copy vs deep copy

class Address {
    private String city;
    // конструктор, getter, setter
}

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

public static void main(String[] args) throws CloneNotSupportedException {
    Person original = new Person("John", new Address("Moscow"));
    Person copy = (Person) original.clone();
    
    System.out.println(original.address == copy.address); // true!
    
    copy.address.setCity("SPB");
    System.out.println(original.address.getCity()); // SPB — изменился оригинал!
}

Когда использовать shallow copy

  • Когда вложенные объекты immutable (строки, числа, LocalDate)
  • Когда не нужно изменять вложенные объекты
  • Для оптимизации памяти и скорости
  • Когда явно требуется поведение shallow copy для синхронизации данных

Когда нужна deep copy

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

Для deep copy переопределяй clone() рекурсивно или используй сериализацию/десериализацию через JSON библиотеки (Jackson, Gson).