Коротка відповідь на "чому не Cloneable
застаріла?" (і справді, чому ні X
для кого не є застарілим X
) - це те, що їх приниження не приділялося багато уваги.
Більшість речей, які були застаріли останнім часом, були застарілими, оскільки існує конкретний план їх видалення. Наприклад, addPropertyChangeListener
і removePropertyChangeListener
методи LogManager були застаріли в Java SE 8 з наміром видалити їх у Java SE 9. (Причина в тому, що вони надмірно ускладнюють взаємозалежності модулів.) Дійсно, ці API вже видалено з ранньої розробки JDK 9 будує. (Зверніть увагу, що аналогічні виклики слухачів зміни властивостей також були видалені з Pack200
; див. JDK-8029806 .)
Не існує такого подібного плану для Cloneable
та Object.clone()
.
Більш довга відповідь передбачає обговорення подальших запитань, наприклад, що можна очікувати, що трапиться з цими API, які витрати або вигоди буде нараховувати платформу, якщо вони були застарілими, і що повідомляється розробникам, коли застарілий API. Я досліджував цю тему в своїх останніх розмовах JavaOne, " Заборгованість" та "Позбавлення життя" . (Слайди доступні за цим посиланням; відео тут .) Виявляється, сам JDK не був дуже послідовним у використанні депресії. Він використовувався для позначення кількох різних речей, зокрема, наприклад,
Це небезпечно , і ви повинні бути інформовані про ризики , пов'язаних з використанням (приклад: Thread.stop()
, Thread.resume()
, і Thread.suspend()
).
Це буде видалено в майбутньому випуску
Це застаріло, і вам корисно використовувати щось інше (приклад: багато методів в java.util.Date
)
Все це є різними значеннями, і різні підмножини їх застосовуються до різних речей, які застаріли. І деякі підмножини з них застосовуються до речей, які не є застарілими (але, можливо, повинні бути застарілими).
Cloneable
і Object.clone()
"розбиті" в тому сенсі, що вони мають вади дизайну і їх важко правильно використовувати. Однак, clone()
як і раніше кращий спосіб копіювання масивів, і клонування має деяку обмеженість корисності для копіювання екземплярів класів, які ретельно реалізуються. Видалення клонування було б несумісною зміною, яка б порушила багато речей. Операція з клонування може бути повторно реалізована по-іншому, але це, мабуть, буде повільніше, ніж Object.clone()
.
Однак для більшості речей конструктор копій кращий для клонування. Тому, можливо, маркування Cloneable
як "застаріле" або "замінене" чи щось подібне було б доречним. Це скаже розробникам, що вони, ймовірно, хочуть шукати деінде, але це не означатиме, що механізм клонування може бути видалений у майбутньому випуску. На жаль, такого маркера не існує.
За станом на даний момент, здається, що «депресія» передбачає можливе усунення - незважаючи на те, що ніколи не було вилучено малу кількість застарілих функцій - і таким чином, припинення роботи не здається гарантованим для механізму клонування. Можливо, в майбутньому може бути застосоване альтернативне маркування, яке спрямовує розробників використовувати альтернативні механізми замість цього.
ОНОВЛЕННЯ
До звіту про помилку я додав додаткову історію . Френк Єллін, ранній виконавець проекту JVM та співавтор специфікації JVM, зробив деякі коментарі у відповідь на коментар "втрачений у туманах часу" коментар до рекомендації TRC, цитованої в іншій відповіді . Я цитував відповідні частини тут; повне повідомлення знаходиться у звіті про помилку.
У Cloneable немає методів з тієї ж причини, що і у Serializable. Cloneable вказує на властивість класу, а не конкретно говорити про методи, які підтримує клас.
До роздумів нам знадобився нативний метод, щоб зробити дрібну копію Об’єкта. Звідси народився Object.clone (). Також було зрозуміло, що багато класів хочуть перекрити цей метод, і що не кожен клас хотів би бути клонованим. Отже, Cloneable народився, щоб вказати на наміри програміста.
Отже, коротше. Метою Cloneable не було вказувати на те, що у вас відкритий метод clone (). Це означало, що ви хочете клонуватись за допомогою Object.clone (), і саме від реалізації вирішувати, чи робити чи клонування () публічним клоном (), слід було.