Принято считать, что Cloneable
интерфейс в Java сломан. Для этого есть много причин, о которых я не буду упоминать; другие уже сделали это. Это также позиция самих архитекторов Java .
Поэтому у меня вопрос: почему он еще не устарел? Если основная группа разработчиков Java решила, что это не работает, они, должно быть, также рассмотрели вопрос об отказе от поддержки. Каковы их причины против этого (в Java 8 это все еще не устарело )?
Cloneable
широко известна.Ответы:
Существует ошибка , представленная в 1997 году в базу данных ошибок Java о добавлении
clone()
методCloneable
, так что он больше не будет бесполезно. Он был закрыт постановлением "исправлять не буду" и обоснование было следующим:Итак, хотя речь идет не об устаревании , причина не делать Cloneable «устаревшим» заключается в том, что комитет по технической проверке решил, что изменения существующей документации будет достаточно, чтобы сделать этот интерфейс полезным. Так они и сделали. До Java 1.4
Cloneable
было задокументировано следующее:Начиная с версии Java 1.4 (выпущенной в феврале 2002 г.) до текущей версии (Java 8) это выглядит так:
источник
clone
метод былObject
на первом месте?Object#clone()
создает экземпляр того же класса, что и оригинал, без того, чтобы этот класс был известен во время компиляции.Краткий ответ на вопрос "почему не
Cloneable
устарел?" (или, действительно, почему они не являютсяX
устаревшимиX
), заключается в том, что их устареванию не уделялось много внимания.Большинство вещей, которые недавно были объявлены устаревшими, устарели, потому что существует специальный план их удаления. Например, методы
addPropertyChangeListener
и LogManager были объявлены устаревшими в Java SE 8 с намерением удалить их в Java SE 9. (Причина в том, что они излишне усложняли взаимозависимости модулей). Действительно, эти API уже были удалены из ранней разработки JDK 9. строит. (Обратите внимание, что аналогичные вызовы прослушивателя изменения свойств также были удалены ; см. JDK-8029806 .)removePropertyChangeListener
Pack200
Подобных планов не существует для
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, цитируемый в другом ответе . Я процитировал здесь соответствующие части; полное сообщение находится в отчете об ошибке.
источник
Object.clone()
в огонь только потому, что все хотят этого, но вы готовы рассуждать и поднимать из этого положительные моменты.array.clone()
это обязательно быстрее, чем любые альтернативы. С точки зрения API это наиболее лаконичный способ дублирования массива.Arrays.copyOf(array, newlen)
подходит близко, но для этого требуется параметр длины, который является избыточным, если вы не меняете длину.Thread.suspend()
иThread.stop()
(no-arg) опасны, они, вероятно, не будут удалены - или изменены, чтобы безоговорочно генерировать исключение - потому что люди действительно их используют! Предположительно они готовы нести риск. Одним из смягчающих факторов со слушателями изменения свойств является то, что они использовались очень редко, поэтому их удаление незначительно.java.beans
можно сделать независимым,java.desktop
поскольку beans - это всего лишь API библиотеки для свойств. К сожалению, если вы углубитесь в API beans, то увидите, что AWT сильно зависит от него. В реализации даже больше. Конечно, их можно было бы извлечь, но это кажется гораздо большей работой, чем, скажем, отделение журнала от beans. Все усилия по модуляции направлены на то, чтобы сделать это распутывание; несомненно, можно было бы сделать больше, но тогда Jigsaw потребовал бы еще больше времени.Потому что JCP не считает нужным это делать и может никогда этого не сделать. Спроси их. Вы спрашиваете не в том месте.
Никто и никогда ничего не удалит из Java API из-за требований обратной совместимости. В последний раз это произошло при изменении модели событий AWT с 1.0 на 1.1 в 1996/7.
источник
Thread.stop(Throwable)
, изменив свой контракт, чтобы всегда передаватьUnsupportedOperationException
вызывающему (а не целевому потоку!).Thread.stop(Throwable)
Java 8 была удалена функциональность. В любом случае безоговорочный совет «спросить их» неверен, потому что сегодня сам главный архитектор Java является активным участником Stack Overflow. Он просто не удосуживается отвечать ни на что, кроме вопросов, связанных с Streams.Cloneable
удалятся ли из Java API. Я спрашиваю, почему не собираются развращать. И я думаю, что это идеальное место, чтобы спросить.