§11 Переопределяйте clone() избирательно
interface Cloneable –Особенность Object.clone() –Уникальность интерфейса
Стандарт JSE6 - clone() : Создает и возвращает копию объекта. Значение «копия» может зависеть от типа объекта. Это значит x.clone() != x x.clone().getClass() == x.getClass() Обычно, но не обязательно x.clone().equals(x) Копирование объекта обычно влечет создание нового экземпляра класса, но может влечь и копирование внутренних структур. Без вызова конструктора.
Требование к отсутствию вызова конструктора – слишком сильное. Если класс final, clone может возвратить созданный внутри объект. Если вы переопределяете clone() в не final классе, то вам следует возращать объект super.clone() От класса реализующего Cloneable ожидается, что в нем будет корректно работающий clone()
Пример Работает начиная 1.5 Не заставляйте пользователя делать то, что вы можете сделать в библиотеке.
Чем плох такой подход:
По сути, clone() работает как конструктор. Вы должны быть уверены, что он не повредит исходный объект, и правильно устанавливает инварианты клона. Архитектура clone() несовместима с нормальным использованием final полей ссылающимися на изменяемые объекты.
The fix
Better fix
Лучше не реализовывать дополнительную функциональность в clone(), а еще лучше не предоставлять такой возможности вообще. Вместо – используйте конструктор копирования, или фабрику копирования public Yum(Yum yum); public static Yum newInstance(Yum Yum);