Il est généralement entendu que l' Cloneable
interface en Java est cassée. Il y a de nombreuses raisons à cela, que je ne mentionnerai pas; d'autres l'ont déjà fait. C'est également la position des architectes Java eux-mêmes.
Ma question est donc la suivante: pourquoi n'est-il pas encore obsolète? Si l'équipe Java de base a décidé qu'elle est cassée, elle doit également avoir envisagé la dépréciation. Quelles sont leurs raisons de ne pas le faire (en Java 8, ce n'est toujours pas obsolète )?
Cloneable
est largement connue.Réponses:
Il y a un bogue soumis en 1997 à la base de données de bogues Java concernant l'ajout de
clone()
méthode àCloneable
, donc ce ne serait plus inutile. Il a été fermé avec la résolution "ne résoudra pas" et la justification était la suivante:Donc, bien que ce ne soit pas directement obsolète , la raison pour ne pas rendre Cloneable "obsolète" est que le Comité de révision technique a décidé que la modification de la documentation existante suffirait à rendre cette interface utile. Et c'est ce qu'ils ont fait. Jusqu'à Java 1.4,
Cloneable
était documenté comme suit:Depuis Java 1.4 (qui a été publié en février 2002) jusqu'à l'édition actuelle (Java 8), cela ressemble à ceci:
la source
clone
méthode était enObject
premier lieu?Object#clone()
produit une instance de la même classe que l'original sans que cette classe soit connue au moment de la compilation.La réponse courte à "pourquoi n'est pas
Cloneable
obsolète?" (ou en fait, pourquoi n'est pasX
obsolète, pour tout le mondeX
) est qu'il n'y a pas eu beaucoup d'attention portée à leur dépréciation.La plupart des éléments qui ont été récemment obsolètes l'ont été, car il existe un plan spécifique pour les supprimer. Par exemple, les méthodes
addPropertyChangeListener
etremovePropertyChangeListener
de LogManager ont été déconseillées dans Java SE 8 avec l'intention de les supprimer dans Java SE 9. (La raison en est qu'elles compliquent inutilement les interdépendances de modules.) En effet, ces API ont déjà été supprimées du développement initial de JDK 9 . construit. (Notez que les appels d'écouteur de changement de propriété similaires ont également été supprimésPack200
; voir JDK-8029806 .)Aucun plan similaire n'existe pour pour
Cloneable
etObject.clone()
.Une réponse plus longue impliquerait de discuter d'autres questions, telles que ce que l'on pourrait s'attendre à ce qu'il arrive à ces API, quels coûts ou avantages la plate-forme gagnerait-elle si elles étaient obsolètes et ce qui est communiqué aux développeurs lorsqu'une API est obsolète. J'ai exploré ce sujet dans ma récente conférence JavaOne, Debt and Deprecation . (Diapositives disponibles sur ce lien; vidéo ici .) Il s'avère que le JDK lui-même n'a pas été très cohérent dans son utilisation de la dépréciation. Il a été utilisé pour signifier plusieurs choses différentes, y compris par exemple,
Ceci est dangereux et vous devriez être au courant des risques de son utilisation ( par exemple:
Thread.stop()
,Thread.resume()
etThread.suspend()
).Cela va être supprimé dans une prochaine version
C'est obsolète et c'est une bonne idée pour vous d'utiliser quelque chose de différent (exemple: de nombreuses méthodes dans
java.util.Date
)Tous ces éléments ont des significations distinctes, et différents sous-ensembles d'entre eux s'appliquent à différentes choses qui sont obsolètes. Et certains sous-ensembles d'entre eux s'appliquent à des choses qui ne sont pas obsolètes (mais qui devraient peut-être être obsolètes).
Cloneable
etObject.clone()
sont «cassés» dans le sens où ils présentent des défauts de conception et sont difficiles à utiliser correctement. Cependant,clone()
c'est toujours le meilleur moyen de copier des tableaux, et le clonage a une utilité limitée pour faire des copies d'instances de classes qui sont soigneusement implémentées. La suppression du clonage serait un changement incompatible qui briserait beaucoup de choses. Une opération de clonage pourrait être réimplémentée d'une manière différente, mais elle serait probablement plus lente queObject.clone()
.Cependant, pour la plupart des choses, un constructeur de copie est préférable au clonage. Alors peut-être que le marquage
Cloneable
comme "obsolète" ou "remplacé" ou quelque chose de similaire serait approprié. Cela indiquerait aux développeurs qu'ils veulent probablement chercher ailleurs, mais cela ne signifierait pas que le mécanisme de clonage pourrait être supprimé dans une prochaine version. Malheureusement, un tel marqueur n'existe pas.Dans l'état actuel des choses, la «dépréciation» semble impliquer une suppression éventuelle - malgré le fait qu'un nombre infime de fonctionnalités obsolètes ait jamais été supprimée - et la dépréciation ne semble donc pas justifiée pour le mécanisme de clonage. Peut-être qu'à l'avenir, un marquage alternatif pourra être appliqué qui incitera les développeurs à utiliser à la place des mécanismes alternatifs.
METTRE À JOUR
J'ai ajouté un historique supplémentaire au rapport de bogue . Frank Yellin, un des premiers implémenteurs de JVM et co-auteur de la spécification JVM, a fait quelques commentaires en réponse au commentaire "perdu dans la brume du temps" dans la recommandation TRC citée dans l' autre réponse . J'ai cité les parties pertinentes ici; le message complet se trouve dans le rapport de bogue.
la source
Object.clone()
dans le feu juste parce que tout le monde le veut, mais que vous soyez prêt à raisonner et à en évoquer les bonnes choses.array.clone()
soit nécessairement plus rapide que toutes les alternatives. Du point de vue de l'API, c'est le moyen le plus concis de dupliquer un tableau.Arrays.copyOf(array, newlen)
se rapproche, mais il nécessite un paramètre de longueur, qui est redondant si vous ne modifiez pas la longueur.Thread.suspend()
etThread.stop()
(no-arg) sont dangereux, ils ne seront probablement pas supprimés - ou modifiés pour lever une exception sans condition - car les gens les utilisent réellement! Ils sont probablement prêts à assumer le risque. L'un des facteurs atténuants avec les écouteurs de changement de propriété est qu'ils ont été utilisés très rarement, de sorte que l'impact de leur suppression est faible.java.beans
pourrait être rendu indépendant dejava.desktop
puisque les beans ne sont qu'une API de bibliothèque pour les propriétés. Malheureusement, si vous creusez dans l'API de beans, il existe de nombreuses dépendances sur AWT. La mise en œuvre a encore plus. Il serait certainement possible de les extraire, mais cela semble être beaucoup plus de travail que, par exemple, de démêler l'exploitation forestière des haricots. Tout l'effort de modularisation consiste à faire ce démêlage; sans aucun doute, plus pourrait être fait, mais alors Jigsaw prendrait encore plus de temps.Parce que le JCP n'a pas jugé bon de le faire et ne le fera peut-être jamais. Leur demander. Vous demandez au mauvais endroit.
Personne ne supprimera jamais quoi que ce soit de l'API Java, en raison de l'exigence de compatibilité descendante. La dernière fois que cela s'est produit, c'était le changement du modèle d'événement AWT entre 1.0 et 1.1 en 1996/7.
la source
Thread.stop(Throwable)
en modifiant son contrat pour toujours lancerUnsupportedOperationException
à l'appelant (pas au thread cible!).Thread.stop(Throwable)
la fonctionnalité de 's s'est produite dans Java 8. Quoi qu'il en soit, le conseil inconditionnel de "leur demander" est faux car aujourd'hui l'architecte en chef Java lui-même est un membre actif de Stack Overflow. Il ne se donne tout simplement pas la peine de répondre à autre chose qu'à des questions liées à Streams.Cloneable
sera supprimé de l'API Java. Je demande pourquoi il ne sera pas supprimé. Et je pense que c'est un endroit parfait pour demander.