Подтвердить что ты не робот

Почему бы не включить внутри переопределенного .clone?

Я понимаю, как работает клонирование Java, и аргументы против его использования. Позволяет сказать, что я все равно мертв, используя его.

Для удобства я хотел бы написать метод clone для класса Foo следующим образом:

@Override
public Foo clone(){
    Foo f = (Foo)super.clone();
    //Replace mutable fields
    return f;
}

Насколько я могу судить, это было бы безопасно. Однако я заметил, что классы Cloneable в API не делают этого. Есть ли причина для этого, и это плохой стиль?

4b9b3361

Ответ 1

Перед Java 5 ковариантные типы возвращаемых данных вообще не разрешались, поэтому Foo clone() даже не компилировался. Поскольку много классов Cloneable было написано давно, возможно, причина большинства случаев.

Я подозреваю, что новые классы не используют его просто потому, что clone(), как известно, довольно горст, и когда люди редко его используют, они даже не думают, что могут его использовать. Они находят некоторые "как реализовать запрос clone()" и записывают код по-старому.

Ответ 2

Object.clone() создает новый объект, где все поля имеют то же значение, что и оригинал. Для полей ссылочного типа это означает, что новое поле является просто ссылкой на тот же объект, что и исходный. Это не поля clone. Поэтому во многих случаях реализация по умолчанию приведет к совместным данным, что может быть нежелательным. Например, если ArrayList.clone() использовал реализацию по умолчанию, вы получили бы два экземпляра ArrayList, имеющих один и тот же массив поддержки.

Если все поля объекта неизменяемы, может быть хорошей идеей просто привести результат super.clone() к соответствующему типу.

Ответ 3

Хм, это определенно не плохой стиль, на самом деле его предпочтительнее, если вы делаете это с момента выпуска java 1.5, потому что ковариантные типы возврата были представленный в выпуске 1.5 как часть дженериков, и, делая это, вы упрощаете использование вашего API (никакого литья не потребуется).

source (Эффективное java-издание 2).