← Назад к вопросам
Что нужно сделать чтобы реализовать неглубокое копирование?
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"); // изменит и оригинальный список
Ключевые особенности
- Примитивные типы: int, long, boolean и т.д. копируются по значению
- Объекты: копируются по ссылке — новый объект содержит ссылку на старый
- Коллекции: сама коллекция копируется, но элементы остаются теми же
Пример различия 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).