Все подходы для копирования объектов в Java имеют серьезные недостатки:
Clone
- Клон() метод защищен, так что вы не можете назвать это непосредственно, если класс в вопросительных переопределениях это с общедоступным методом.
- clone() не вызывает конструктор. Любой конструктор. Он будет выделять память, назначить внутреннее поле
class
(которое вы можете прочитать через getClass()
) и скопировать поля оригинала.
Для более проблем с клоном() см пункт 11 книги Джошуа Блоха "Effective Java, Second Edition"
Serialize
Сериализация еще хуже; он имеет многие из недостатков clone()
, а затем некоторые. У Джошуа есть целая глава с четырьмя пунктами только для этой темы.
мое решение
Мое решение добавить новый интерфейс для моих проектов:
public interface Copyable<T> {
T copy();
T createForCopy();
void copyTo (T dest);
}
код выглядит следующим образом:
class Demo implements Copyable<Demo> {
public Demo copy() {
Demo copy = createForCopy();
copyTo (copy);
return copy;
}
public Demo createForCopy() {
return new Demo();
}
public void copyTo (Demo dest)
super.copyTo (dest);
...copy fields of Demo here...
}
}
К сожалению, я должен скопировать этот код ко всем моим объектам, но это всегда один и тот же код, поэтому я могу использовать шаблон редактора Eclipse. Преимущества:
- Я могу решить, какой конструктор вызвать и как инициализировать какое поле.
- Инициализация происходит в неопределенном порядке (корневой класс для класса экземпляра)
- можно повторно использовать существующие объекты и перезаписать их
- типобезопасен
- Singletons остаться одиночками
Для стандартных типов Java (например, коллекции и т. д.), я использую класс утилиты, который может их скопировать. Методы имеют флаги и обратные вызовы, поэтому я могу контролировать, насколько глубокой должна быть копия.
Возможный дубликат [Как сделать глубокую копию объекта в Java?] (Http://stackoverflow.com/questions/64036/how-do-you-make-a-deep-copy-of- a-object-in-java) –