Je ne comprends pas pourquoi il n'y a pas d'héritage dans les annotations Java, tout comme les classes Java. Je pense que ce serait très utile.
Par exemple: je veux savoir si une annotation donnée est un validateur. Avec l'héritage, je pourrais naviguer par réflexe dans les superclasses pour savoir si cette annotation étend a ValidatorAnnotation
. Sinon, comment puis-je y parvenir?
Alors, quelqu'un peut-il me donner une raison pour cette décision de conception?
java
inheritance
annotations
sinuhepop
la source
la source
java.lang.annotation.Annotation
, c'est-à-dire que toute annotation l'estinstanceof
bien que ce fait ne soit pas explicitement déclaré.Réponses:
À propos de la raison pour laquelle il n'a pas été conçu de cette façon, vous pouvez trouver la réponse dans la FAQ de conception JSR 175 , où il est dit:
Donc, oui, je suppose, la raison en est juste KISS. Quoi qu'il en soit, il semble que ce problème (ainsi que de nombreux autres) soit examiné dans le cadre de JSR 308 , et vous pouvez même trouver un compilateur alternatif avec cette fonctionnalité déjà développée par Mathias Ricken .
la source
Les annotations extensibles ajouteraient effectivement la charge de spécifier et de maintenir un autre type de système. Et ce serait un système de type assez unique, vous ne pourriez donc pas simplement appliquer un paradigme de type OO.
Réfléchissez à tous les problèmes lorsque vous introduisez le polymorphisme et l'héritage dans une annotation (par exemple, que se passe-t-il lorsque la sous-annotation modifie les spécifications de méta-annotation telles que la rétention?)
Et toute cette complexité supplémentaire pour quel cas d'utilisation?
Vous voulez savoir si une annotation donnée appartient à une catégorie?
Essaye ça:
Comme vous pouvez le voir, vous pouvez facilement regrouper et classer les annotations sans douleur excessive en utilisant les fonctionnalités fournies.
Ainsi, KISS est la raison pour ne pas introduire un système de type méta-type dans le langage Java.
[ps modifier]
J'ai utilisé la chaîne simplement pour la démonstration et en vue d'une méta annotation ouverte. Pour votre propre projet, vous pouvez évidemment utiliser une énumération de types de catégories et spécifier plusieurs catégories ("héritage multiple") pour une annotation donnée. Notez que les valeurs sont entièrement fausses et à des fins de démonstration uniquement:
la source
@Target(ElementType.ANNOTATION_TYPE) @Retention(RetentionPolicy.RUNTIME) @interface C {}; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @C public @interface F {} class a{ @F public void S() {} } @Test public void blahTest() throws NoSuchMethodException { Method m = a.class.getMethod("S"); System.out.println(m.isAnnotationPresent(C.class)); }
Dans un sens, vous l'avez déjà avec Annotations - meta Annotations. Si vous annotez une annotation avec des métadonnées, cela équivaut à bien des égards à l'extension d'une interface supplémentaire. Les annotations sont des interfaces, donc le polymorphisme n'entre pas vraiment en jeu, et comme elles sont de nature statique, il ne peut y avoir de répartition dynamique à l'exécution.
Dans votre exemple de validateur, vous pouvez simplement sur l'annotation obtenir le type annoté et voir s'il a une méta-annotation de validateur.
Le seul cas d'utilisation que j'ai pu voir que l'héritage serait utile si vous vouliez pouvoir obtenir l'annotation par super type, mais cela ajouterait beaucoup de complexité, car une méthode ou un type donné peut avoir deux annotations de ce type, ce qui signifie qu'un tableau devrait être retourné au lieu d'un seul objet.
Je pense donc que la réponse ultime est que les cas d'utilisation sont ésotériques et compliquent des cas d'utilisation plus standard, ce qui ne vaut pas la peine.
la source
Les concepteurs de la prise en charge des annotations Java ont effectué un certain nombre de «simplifications» au détriment de la communauté Java.
Aucun sous-type d'annotations ne rend la plupart des annotations complexes inutilement laides. On ne peut pas simplement avoir un attribut dans une annotation qui peut contenir une des trois choses. Il faut avoir trois attributs distincts, ce qui déroute les développeurs et nécessite une validation d'exécution pour garantir qu'un seul des trois est utilisé.
Une seule annotation d'un type donné par site. Cela a conduit au modèle d'annotation de collection complètement inutile. @Validation et @Validations, @Image et @Images, etc.
Le second est corrigé dans Java 8, mais il est trop tard. De nombreux frameworks ont été écrits sur la base de ce qui était possible dans Java 5 et maintenant, ces verrues API sont là pour rester longtemps.
la source
J'ai peut-être trois ans de retard pour répondre à cette question, mais je l'ai trouvée intéressante parce que je me suis retrouvée au même endroit. Voici mon point de vue là-dessus. Vous pouvez afficher les annotations sous forme d'énumérations. Ils fournissent un type d'information à sens unique - utilisez-le ou perdez-le.
J'ai eu une situation où je voulais simuler GET, POST, PUT et DELETE dans une application Web. Je voulais tellement avoir une "super" annotation qui s'appelait "HTTP_METHOD". Il m'est apparu plus tard que cela n'avait pas d'importance. Eh bien, j'ai dû me contenter d'utiliser un champ caché dans le formulaire HTML pour identifier DELETE et PUT (car POST et GET étaient disponibles de toute façon).
Côté serveur, j'ai recherché un paramètre de requête caché avec le nom "_method". Si la valeur était PUT ou DELETE, elle a remplacé la méthode de requête HTTP associée. Cela dit, peu importait que j'aie ou non besoin d'étendre une annotation pour faire le travail. Toutes les annotations se ressemblaient, mais elles étaient traitées différemment côté serveur.
Donc, dans votre cas, supprimez la démangeaison pour étendre les annotations. Traitez-les comme des «marqueurs». Ils "représentent" certaines informations et ne "manipulent" pas nécessairement certaines informations.
la source
Une chose à laquelle je pourrais penser est la possibilité d'avoir plusieurs annotations. Vous pouvez donc ajouter un validateur et une annotation plus spécifique au même endroit. Mais je peux me tromper :)
la source
Je n'y ai jamais pensé mais ... semble que vous avez raison, il n'y a aucun problème avec la fonction d'héritage des annotations (au moins je ne vois pas le problème avec ça).
À propos de votre exemple avec l' annotation «validateur» - vous pouvez alors exploiter l' approche «méta-annotation» . C'est-à-dire que vous appliquez une méta-annotation particulière à l'ensemble de l'interface d'annotation.
la source
le même problème que j'ai. Non, tu ne peux pas. Je me suis «discipliné» pour écrire des propriétés dans des annotations afin de respecter certaines normes, donc à l'extérieur lorsque vous obtenez une annotation, vous pouvez «renifler» le type d'annotation qu'il s'agit en fonction des propriétés qu'il possède.
la source