Расскажите про клонирование объектов.
Использование оператора присваивания не создает нового объекта, а лишь копирует ссылку на объект. Таким образом, две ссылки указывают на одну и ту же область памяти, на один и тот же объект. Для создания нового объекта с таким же состоянием используется клонирование объекта.
Класс
Чтобы окончательно сделать объект клонируемым, класс должен реализовать интерфейс
Это решение эффективно только в случае, если поля клонируемого объекта представляют собой значения базовых типов и их обёрток или неизменяемых
Такое клонирование возможно только в случае, если тип атрибута класса также реализует интерфейс
Помимо встроенного механизма клонирования в
• Специализированный конструктор копирования - в классе описывается конструктор, который принимает объект этого же класса и инициализирует поля создаваемого объекта значениями полей переданного.
• Фабричный метод - (Factory method), который представляет собой статический метод, возвращающий экземпляр своего класса.
• Механизм сериализации - сохранение и последующее восстановление объекта в/из потока байтов.
Использование оператора присваивания не создает нового объекта, а лишь копирует ссылку на объект. Таким образом, две ссылки указывают на одну и ту же область памяти, на один и тот же объект. Для создания нового объекта с таким же состоянием используется клонирование объекта.
Класс
Object
содержит protected
метод clone()
, осуществляющий побитовое копирование объекта производного класса. Однако сначала необходимо переопределить метод clone()
как public
для обеспечения возможности его вызова. В переопределенном методе следует вызвать базовую версию метода super.clone()
, которая и выполняет собственно клонирование.Чтобы окончательно сделать объект клонируемым, класс должен реализовать интерфейс
Cloneable
. Интерфейс Cloneable
не содержит методов относится к маркерным интерфейсам, а его реализация гарантирует, что метод clone()
класса Object
возвратит точную копию вызвавшего его объекта с воспроизведением значений всех его полей. В противном случае метод генерирует исключение CloneNotSupportedException
. Следует отметить, что при использовании этого механизма объект создается без вызова конструктора.Это решение эффективно только в случае, если поля клонируемого объекта представляют собой значения базовых типов и их обёрток или неизменяемых
(immutable)
объектных типов. Если же поле клонируемого типа является изменяемым ссылочным типом, то для корректного клонирования требуется другой подход. Причина заключается в том, что при создании копии поля оригинал и копия представляют собой ссылку на один и тот же объект. В этой ситуации следует также клонировать и сам объект поля класса.Такое клонирование возможно только в случае, если тип атрибута класса также реализует интерфейс
Cloneable
и переопределяет метод clone()
. Так как, если это будет иначе вызов метода невозможен из-за его недоступности. Отсюда следует, что если класс имеет суперкласс, то для реализации механизма клонирования текущего класса-потомка необходимо наличие корректной реализации такого механизма в суперклассе. При этом следует отказаться от использования объявлений final
для полей объектных типов по причине невозможности изменения их значений при реализации клонирования.Помимо встроенного механизма клонирования в
Java
для клонирования объекта можно использовать:• Специализированный конструктор копирования - в классе описывается конструктор, который принимает объект этого же класса и инициализирует поля создаваемого объекта значениями полей переданного.
• Фабричный метод - (Factory method), который представляет собой статический метод, возвращающий экземпляр своего класса.
• Механизм сериализации - сохранение и последующее восстановление объекта в/из потока байтов.