Question

Je ne comprends pas pourquoi il n'y a pas d'héritage dans les annotations Java, comme dans 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 pouvais naviguer par réflexe dans les superclasses pour savoir si cette annotation étendait un ValidatorAnnotation . Sinon, comment puis-je y parvenir?

Alors, est-ce que quelqu'un peut me donner une raison pour cette décision de conception?

Était-ce utile?

La solution

Pour la raison pour laquelle il n'a pas été conçu de cette manière, vous pouvez trouver la réponse dans le JSR 175 FAQ sur les conceptions, où il est indiqué:

  

Pourquoi ne pas prendre en charge le sous-typage d'annotation (lorsqu'un type d'annotation en étend un autre)?

     

Cela complique le type d'annotation   système, et le rend beaucoup plus   difficile à écrire & # 8220; Outils spécifiques & # 8221;.

     

& # 8230;

     

& # 8220; Outils spécifiques & # 8221; & # 8212; Programmes qui interrogent   types d'annotation connus d'arbitraire   programmes externes. Générateurs de stub,   par exemple, tombent dans cette catégorie.   Ces programmes se liront annotés   classes sans les charger dans le   machine virtuelle, mais chargera   interfaces d'annotation.

Donc, oui, je suppose, la raison en est que KISS. Quoi qu'il en soit, il semble que cette question (parmi tant d'autres) soit examinée 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 .

Autres conseils

Les annotations extensibles ajouteraient effectivement la charge de la spécification et de la gestion d’un autre système de types. Et ce serait un système de type assez unique, vous ne pouvez 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?

Essayez ceci:

@Target(ElementType.ANNOTATION_TYPE)
public @interface Category {
    String category();
}

@Category(category="validator")
public @interface MyFooBarValidator {

}

Comme vous pouvez le constater, vous pouvez facilement regrouper et catégoriser des annotations sans douleur inutile à l’aide des installations fournies.

Ainsi, KISS est la raison pour laquelle aucun système de type méta-type n'a été introduit dans Java. langue.

[p.s. modifier]

J'ai utilisé la chaîne simplement à des fins de 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égorie et spécifier plusieurs catégories ("héritage multiple") pour une annotation donnée. Notez que les valeurs sont entièrement fictives et à des fins de démonstration uniquement:

@Target(ElementType.ANNOTATION_TYPE)
public @interface Category {
    AnnotationCategory[] category();
}
public enum AnnotationCategory {
    GENERAL,
    SEMANTICS,
    VALIDATION,
    ETC
}

@Category(category={AnnotationCategory.GENERAL, AnnotationCategory.SEMANTICS})
public @interface FooBarAnnotation {

}

En un sens, vous l’avez déjà sous 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 étant des interfaces, le polymorphisme n'entre donc pas en jeu. De plus, comme elles sont de nature statique, il ne peut y avoir de distribution dynamique à l'exécution.

Dans votre exemple de validateur, vous pouvez simplement obtenir sur l'annotation le type annoté et voir s'il contient une méta-annotation de validateur.

Le seul cas d'utilisation qui me soit utile en ce qui concerne l'héritage est celui de 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. dessus, ce qui signifie qu’un tableau devrait être renvoyé 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 davantage les cas d'utilisation standard, ce qui en fait une valeur inutile.

Les concepteurs du support des annotations Java ont créé un certain nombre de "simplifications". au détriment de la communauté Java.

  1. Aucun sous-type d’annotations ne rend inutilement laides de nombreuses annotations complexes. On ne peut pas simplement avoir dans les annotations un attribut pouvant contenir l'une des trois choses suivantes. Il faut disposer de trois attributs distincts, ce qui déroute les développeurs et nécessite une validation à l'exécution pour garantir que seul l'un des trois est utilisé.

  2. Une seule annotation d'un type donné par site. Cela a conduit à un motif d'annotation de collection complètement inutile. @Validation et @Validations, @Image et @Images, etc.

Le deuxième problème est en cours de résolution dans Java 8, mais il est trop tard. De nombreux frameworks ont été écrits sur la base des possibilités de Java 5 et maintenant, ces verrous d’API sont là pour rester longtemps.

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:)

Je n'ai jamais pensé à ça, mais ... semble avoir raison, il n'y a pas de problème avec la fonction d'héritage d'annotations (du moins, je ne vois pas le problème avec cela).

À propos de votre exemple avec l'annotation 'validator' - vous pouvez alors exploiter l'approche 'méta-annotation' . C'est à dire. vous appliquez une méta-annotation particulière à l'ensemble de l'interface d'annotation.

J'ai peut-être trois ans de retard pour répondre à cette question, mais je l’ai trouvée intéressante, car 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 des informations à sens unique - utilisez-les ou perdez-les.

J'étais dans une situation où je voulais simuler GET, POST, PUT et DELETE dans une application Web. Je voulais tellement avoir un "super" Une annotation appelée "HTTP_METHOD". Plus tard, j'ai compris que cela n'avait pas d'importance. Eh bien, j’ai dû accepter d’utiliser un champ caché dans le formulaire HTML pour identifier DELETE et PUT (car POST et GET étaient quand même disponibles).

Côté serveur, j'ai recherché un paramètre de requête masqué portant le nom "_method". Si la valeur était PUT ou DELETE, alors la méthode de requête HTTP associée était remplacée. Cela dit, peu importait si je devais étendre une annotation pour que le travail soit effectué. Toutes les annotations étaient identiques, mais elles étaient traitées différemment côté serveur.

Donc, dans votre cas, supprimez la gale pour étendre les annotations. Traitez-les comme des "marqueurs". Ils " représentent " certaines informations, et pas nécessairement "manipuler" quelques informations.

le même problème que j'ai. Non, tu ne peux pas. Je me suis «discipliné» moi-même pour écrire les propriétés dans les annotations afin de respecter certaines normes. Ainsi, lorsque vous obtenez une annotation, vous pouvez «identifier» le type d'annotation utilisé en fonction des propriétés dont il dispose.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top