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

Что такое Copy Constructor?

2.0 Middle🔥 161 комментариев
#Основы Java

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

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

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

Copy Constructor в Java

Copy Constructor (конструктор копирования) — это специальный конструктор, который создаёт новый объект как копию уже существующего объекта того же класса. В Java эта концепция менее распространена, чем в C++, но остаётся важной для понимания проектирования классов.

Определение

Copy Constructor принимает объект того же класса как параметр и создаёт его полную копию:

public class Person {
    private String name;
    private int age;
    private Address address; // сложный объект
    
    // Обычный конструктор
    public Person(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
    
    // Copy Constructor
    public Person(Person other) {
        this.name = other.name;
        this.age = other.age;
        // Важно: создаём НОВЫЙ объект для address
        this.address = new Address(other.address);
    }
    
    public String getName() { return name; }
    public int getAge() { return age; }
    public Address getAddress() { return address; }
}

public class Address {
    private String city;
    private String street;
    
    public Address(String city, String street) {
        this.city = city;
        this.street = street;
    }
    
    // Copy Constructor
    public Address(Address other) {
        this.city = other.city;
        this.street = other.street;
    }
}

Использование

// Создание оригинального объекта
Address address = new Address("Moscow", "Tverskaya");
Person original = new Person("John", 30, address);

// Создание копии через Copy Constructor
Person copy = new Person(original);

// Теперь у нас есть две независимые копии
original.getAddress().setCity("SPB");
System.out.println(copy.getAddress().getCity()); // Moscow — не изменился!

Глубокое копирование vs Поверхностное

Поверхностное копирование (Shallow Copy):

public Person(Person other) {
    this.name = other.name;        // OK: String immutable
    this.age = other.age;          // OK: примитив
    this.address = other.address;  // ПРОБЛЕМА: та же ссылка!
}

// Проблема:
Person copy = new Person(original);
original.getAddress().setCity("SPB");
System.out.println(copy.getAddress().getCity()); // SPB — скопирована ссылка!

Глубокое копирование (Deep Copy):

public Person(Person other) {
    this.name = other.name;
    this.age = other.age;
    this.address = new Address(other.address);  // Новый объект!
}

Альтернативы в Java

1. Метод clone()

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

// Использование
Person copy = original.clone();

Проблемы:

  • Checked Exception
  • Поверхностное копирование по умолчанию
  • Нужна реализация Cloneable

2. Конструктор с другими параметрами

public Person(String name, int age, Address address) {
    // можно использовать как обычный или как копирующий
}

3. Builder Pattern

public class PersonBuilder {
    private String name;
    private int age;
    
    public PersonBuilder(Person original) {
        this.name = original.name;
        this.age = original.age;
    }
    
    public Person build() {
        return new Person(name, age);
    }
}

4. Библиотеки (MapStruct, ModelMapper)

// Автоматическое копирование
PersonDTO dto = modelMapper.map(person, PersonDTO.class);

Когда использовать Copy Constructor

  • Immutable объекты — когда нужна гарантия, что копия независима
  • Защита от внешних изменений — при передаче объектов между методами
  • Кэширование — когда нужны несколько версий объекта
  • Пулы объектов — для создания предконфигурированных копий
  • Сложные структуры данных — для полной изоляции

Особенности в Java

  1. Нет встроенной поддержки — нужно писать вручную
  2. Immutable fields помогают — String, Integer и т.д. не нужно копировать
  3. Collections нужно копировать — List, Map, Set требуют глубокого копирования
  4. Null-safety — нужно проверять null в конструкторе
public Person(Person other) {
    if (other == null) {
        throw new IllegalArgumentException("Cannot copy null");
    }
    this.name = other.name;
    this.age = other.age;
}

Copy Constructor — это полезный паттерн для обеспечения независимости объектов и предотвращения неожиданных побочных эффектов в многопоточных или сложных приложениях.