Clone () vs Copy constructor – который рекомендуется в java

clone vs copy в java. который является правильным решением. где использовать каждый случай?

Клон сломан, поэтому не используйте его.

МЕТОД КЛОНА classа Object – это несколько волшебный метод, который делает то, что никогда не может сделать чистый метод Java: он создает идентичную копию своего объекта. Он присутствует в первозданном суперclassе classа с момента выпуска бета-версии Java-компилятора *; и он, как и всякая древняя магия, требует соответствующего заклинания, чтобы предотвратить неожиданное оскорбление заклинания

Предпочитает метод, который копирует объект

 Foo copyFoo (Foo foo){ Foo f = new Foo(); //for all properties in FOo f.set(foo.get()); return f; } 

Подробнее http://adtmag.com/articles/2000/01/18/effective-javaeffective-cloning.aspx

Имейте в виду, что clone() не работает из коробки. Вам придется реализовать Cloneable и переопределить метод clone() созданный public .

Есть несколько альтернатив, которые предпочтительнее (так как метод clone() имеет множество проблем с дизайном, как указано в других ответах), а для копирования-конструктора потребуется ручная работа:

  • BeanUtils.cloneBean(original) создает неглубокий клон, как тот, который был создан Object.clone() . (этот class – от обыкновенных бханутов )

  • SerializationUtils.clone(original) создает глубокий клон. (т. е. клонит весь граф свойств, а не только первый уровень) (из commons-lang ), но все classы должны реализовывать Serializable

  • Библиотека глубокого клонирования Java предлагает глубокое клонирование без необходимости реализации Serializable

clone () был разработан с несколькими ошибками (см. этот вопрос ), поэтому лучше избегать его.

Из Effective Java 2nd Edition , пункт 11: разумно переопределить клон

Учитывая все проблемы, связанные с Cloneable, можно с уверенностью сказать, что другие интерфейсы не должны расширять его, а classы, предназначенные для наследования (пункт 17), не должны реализовывать его. Из-за многих недостатков некоторые экспертные программисты просто не рекомендуют переопределять метод клонирования и никогда не вызывать его, кроме, возможно, для копирования массивов. Если вы создаете class для наследования, имейте в виду, что если вы решите не предоставлять хорошо защищенный метод клонирования, для подclassов невозможно реализовать Cloneable.

В этой книге также описываются многие преимущества, которые создатели копий имеют над Cloneable / clone.

  • Они не полагаются на механизм создания экстралингвистического объекта, подверженного риску
  • Они не требуют необоснованного соблюдения тонко документированных конвенций
  • Они не противоречат правильному использованию конечных полей
  • Они не выбрасывают ненужные проверенные исключения
  • Они не требуют отбрасываний.

Все стандартные коллекции имеют конструкторы копирования. Используй их.

 List original = // some list List copy = new ArrayList(original); 

Имейте в виду, что конструктор копирования ограничивает тип classа экземпляром конструктора копирования. Рассмотрим пример:

 // Need to clone person, which is type Person Person clone = new Person(person); 

Это не работает, если person может быть подclassом Person (или если Person является интерфейсом). В этом весь смысл клона – это то, что он может динамически клонировать правильный тип во время выполнения (предполагая, что клон правильно реализован).

 Person clone = (Person)person.clone(); 

или

 Person clone = (Person)SomeCloneUtil.clone(person); // See Bozho's answer 

Теперь person может быть любым типом Person предполагающим, что clone правильно реализован.

См. Также: Как правильно переопределить метод клонирования? , Клонирование нарушено на Java, так сложно понять все правильно, и даже когда это происходит , на самом деле это не очень много , поэтому на самом деле это не стоит того.

Великая печаль: ни Клонируемый / клон, ни конструктор – отличные решения: Я НЕ ХОЧУ ЗНАТЬ ИСПОЛНИТЕЛЬНЫЙ КЛАСС !!! (например, у меня есть карта, которую я хочу скопировать, используя ту же скрытую реализацию MumbleMap), я просто хочу сделать копию, если это поддерживается. Но, увы, Cloneable не имеет клона метод на нем, поэтому нет ничего, к которому можно безопасно вводить тип, на который нужно вызвать clone ().

Какая бы ни была лучшая библиотека «экземпляр-копия», Oracle должна сделать ее стандартным компонентом следующей версии Java (если она уже не скрыта где-то).

Конечно, если бы большая часть библиотеки (например, «Коллекции») была неизменной, эта задача «копировать» просто исчезла бы. Но тогда мы начали бы разрабатывать Java-программы с такими вещами, как «инварианты classа», а не с шаблоном «bean» verdammt (сделать сломанный объект и мутировать до хорошего [достаточно]).

  • Как измерить время, прошедшее на Java?
  • Разница между FetchType LAZY и EAGER в Java Persistence API?
  • Как я могу перебирать карту из ?
  • Как избежать Java-кода в JSP-файлах?
  • Сравнение чисел в Java
  • java.lang.NoClassDefFoundError: Не удалось инициализировать class XXX
  • Использование котировок в getRuntime (). Exec
  • Учитывая, что последний блок не заполнен неправильно
  • Java MVC - Как разделить сделанную текстовую игру на MVC?
  • Сочетание строк в Java всегда приводит к созданию новых строк в памяти?
  • Как сделать AWT Button () и использовать ImageIcon (), Icon ()?
  • Давайте будем гением компьютера.