Цель клонирования в Java

Я изучал «особые» особенности Java и начал читать клонирование.

Поэтому в настоящее время я понимаю, что клонирование можно использовать для получения идентичной копии объекта. Для этого вы реализуете интерфейс Cloneable и переопределяете метод клонирования Object (что действительно странно для IMO)

Мои вопросы больше относятся к сравнению C ++ и Java. Почему именно отдельный метод клонирования требуется, когда у нас уже есть поддержка конструкторов копирования. Была ли историческая причина того, почему клонирование считалось обязательным?

PS: я не спрашиваю о необходимости «клонировать» как в зачем клонировать объект в Java, я спрашиваю о необходимости Cloneable и метода clone, когда Java уже поддерживает конструкторы копирования.

1

Решение

ИМО твой вопрос состоит из двух частей.

Что нужно для Cloneable интерфейс?

Cloneable интерфейс также известен как интерфейс маркера, это означает, что у него нет никаких методов, его цель — сообщить пользователю этого класса, что он реализует Клон () метод, который унаследован от объекта. Это позволяет выполнить проверку перед вызовом метода clone ():

Animal a = new Dog();
Animal b;
if (a instanceof Cloneable)
b = a.clone();

Это происходит довольно часто в Java; см. например Сериализуемый интерфейс.

Зачем Java нужна Клон () метод вообще, как у него уже есть конструкторы копирования?

Очень короткий ответ полиморфизм. Как бы вы правильно клонировали экземпляр Dog с помощью ссылки на Animal, его суперкласс, если у вас не было Клон () метод?

1

Другие решения

Клон предназначен для предоставления отдельного экземпляра объекта без уничтожения клонированного. Это довольно полезно (обязательно) в шаблоне прототипа.

Конструктор копирования обычно вызывается в C ++ при передаче по значению (вы также можете использовать его во время конструирования, но обычно он вызывается при передаче объектов через стек либо в качестве параметров, либо в виде возврата). Очень часто первоначальный объект выходит из области видимости.

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

Помимо устранения неоднозначности имени, вам нужно подумать о полиморфизме, когда вы хотите клонировать объект из базового указателя.

Конструкторы копирования будут вызываться по типу указателя, а клон (если он виртуальный, как и должно быть) будет вызываться в самой производной реализации.

0