Die kurze Antwort auf "Warum ist nicht Cloneable
veraltet?" (oder in der Tat, warum wird es nicht X
veraltet X
) ist, dass nicht viel darauf geachtet wurde, sie zu verwerfen.
Die meisten Dinge, die kürzlich veraltet waren, wurden veraltet, weil es einen bestimmten Plan gibt, sie zu entfernen. Zum Beispiel können die addPropertyChangeListener
und removePropertyChangeListener
Methoden der LogManager wurden als veraltet in Java SE 8 (ist der Grund , dass sie Modul Interdependenzen unnötig kompliziert.) Mit der Absicht, sie in Java SE 9. Entfernen der Tat haben diese APIs bereits von Anfang JDK 9 entfernt Entwicklung baut. (Beachten Sie, dass ähnliche Listener-Aufrufe zur Änderung von Eigenschaften auch aus entfernt wurden Pack200
; siehe JDK-8029806 .)
Für Cloneable
und gibt es keinen ähnlichen Plan Object.clone()
.
Eine längere Antwort würde die Erörterung weiterer Fragen beinhalten, z. B. was mit diesen APIs zu erwarten ist, welche Kosten oder Vorteile der Plattform entstehen würden, wenn sie veraltet wären, und was den Entwicklern mitgeteilt wird, wenn eine API veraltet ist. Ich habe dieses Thema in meinem letzten JavaOne-Vortrag " Schulden und Verfall" untersucht . (Folien unter diesem Link verfügbar; Video hier .) Es stellt sich heraus, dass das JDK selbst in seiner Verwendung von Verfall nicht sehr konsistent war. Es wurde verwendet, um verschiedene Dinge zu bedeuten, einschließlich zum Beispiel:
Dies ist gefährlich , und Sie sollten die Risiken der Verwendung es bewusst sein (Beispiel: Thread.stop()
, Thread.resume()
, und Thread.suspend()
).
Dies wird in einer zukünftigen Version entfernt
Dies ist veraltet und es ist eine gute Idee, etwas anderes zu verwenden (Beispiel: viele der Methoden in java.util.Date
)
All dies sind unterschiedliche Bedeutungen, und verschiedene Untergruppen davon gelten für verschiedene Dinge, die veraltet sind. Und einige Untergruppen davon gelten für Dinge, die nicht veraltet sind (die aber möglicherweise veraltet sein sollten).
Cloneable
und Object.clone()
sind "kaputt" in dem Sinne, dass sie Designfehler aufweisen und schwer richtig zu verwenden sind. Dies clone()
ist jedoch immer noch der beste Weg, um Arrays zu kopieren, und das Klonen ist nur begrenzt nützlich, um Kopien von Instanzen von Klassen zu erstellen, die sorgfältig implementiert wurden. Das Entfernen des Klonens wäre eine inkompatible Änderung, die viele Dinge kaputt machen würde. Ein Klonvorgang könnte auf andere Weise erneut implementiert werden, wäre aber wahrscheinlich langsamer als Object.clone()
.
In den meisten Fällen ist jedoch ein Kopierkonstruktor dem Klonen vorzuziehen. Vielleicht Cloneable
wäre es angebracht , sie als "veraltet" oder "ersetzt" oder ähnliches zu markieren . Dies würde Entwicklern mitteilen, dass sie wahrscheinlich woanders suchen möchten, aber es würde nicht signalisieren, dass der Klonmechanismus in einer zukünftigen Version möglicherweise entfernt wird. Leider existiert kein solcher Marker.
Aus heutiger Sicht scheint "Abwertung" eine eventuelle Entfernung zu bedeuten - trotz der Tatsache, dass eine verschwindend kleine Anzahl veralteter Features jemals entfernt wurde - und daher scheint eine Abwertung für den Klonmechanismus nicht gerechtfertigt zu sein. Vielleicht kann in Zukunft eine alternative Kennzeichnung angewendet werden, die Entwickler anweist, stattdessen alternative Mechanismen zu verwenden.
AKTUALISIEREN
Ich habe dem Fehlerbericht einen zusätzlichen Verlauf hinzugefügt . Frank Yellin, ein früher JVM-Implementierer und Mitautor der JVM-Spezifikation, gab einige Kommentare als Antwort auf den Kommentar "Verloren im Nebel der Zeit" in der in der anderen Antwort zitierten TRC-Empfehlung ab . Ich habe die relevanten Teile hier zitiert; Die vollständige Meldung befindet sich im Fehlerbericht.
Cloneable hat aus dem gleichen Grund keine Methoden wie Serializable. Klonbar gibt eine Eigenschaft der Klasse an, anstatt speziell etwas über die von der Klasse unterstützten Methoden zu sagen.
Vor der Reflexion benötigten wir eine native Methode, um eine flache Kopie eines Objekts zu erstellen. Daher wurde Object.clone () geboren. Es war auch klar, dass viele Klassen diese Methode überschreiben möchten und dass nicht jede Klasse geklont werden möchte. Daher wurde Cloneable geboren, um die Absicht des Programmierers anzuzeigen.
Kurz gesagt. Der Zweck von Cloneable bestand nicht darin, anzuzeigen, dass Sie eine öffentliche clone () -Methode hatten. Dies sollte darauf hinweisen, dass Sie bereit waren, mit Object.clone () geklont zu werden, und es lag an der Implementierung, zu entscheiden, ob clone () veröffentlicht werden soll oder nicht.