249 votes

Pourquoi n'est-il pas possible d'étendre les annotations en Java?

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 une ValidatorAnnotation. Sinon, comment puis-je y parvenir?

Alors, quelqu'un peut-il me donner une raison pour laquelle cette décision de conception?

180voto

pedromarce Points 3036

À 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 JSR 175 Conception FAQ, où il est dit:

Pourquoi ne soutenez-vous pas d'annotation de sous-typage (où un type d'annotation s'étend un autre)?

Cela complique le type d'annotation système, et le rend beaucoup plus difficile d'écrire "des Outils Spécifiques".

...

"Des Outils spécifiques" - les Programmes de requête connu les types d'annotation de l'arbitraire des programmes externes. Stub générateurs, par exemple, entrent dans cette catégorie. Ces programmes vont lire annoté des classes sans les charger dans le de la machine virtuelle, mais vous permettra de charger annotation des interfaces.

Donc, oui, je suppose, la raison c'est juste de l'EMBRASSER. De toute façon, il semble que ce problème (avec beaucoup d'autres) sont étudiés dans le cadre de la JSR 308, et vous pouvez même trouver un autre compilateur avec cette fonctionnalité, déjà développé par Mathias Ricken.

J'espère que cela répond à votre question...

72voto

alphazero Points 17514

Extensible annotations serait effectivement ajouter le fardeau de la précisant et en maintenant un autre type de système. Et ce serait assez unique type de système, de sorte que vous ne pouvait tout simplement appliquer un OO type de paradigme.

Réfléchir à toutes les questions lors de l'introduction d'polymorphisme et l'héritage d'une annotation (par exemple ce qui arrive quand les sous-annotation des changements de méta-annotation spécifications tels que la rétention?)

Et tout cela ajoute à la complexité de ce cas d'utilisation?

Vous voulez savoir si une annotation 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 voir, vous pouvez facilement regrouper et de classer les annotations sans trop de douleur en utilisant les installations.

Donc, le BAISER est la raison de ne pas introduire d'une méta-type de système de type pour le langage Java.

[p.s. modifier]

J'ai utilisé de la Corde à des fins de démonstration et en vue d'une fin ouverte méta-annotation. Pour votre propre projet donné, de toute évidence vous pouvez utiliser une énumération des types de catégories et de spécifier plusieurs catégories ("l'héritage multiple") pour une annotation. Notez que les valeurs sont totalement faux et pour 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 {

}


12voto

Yishai Points 42417

Dans un sens, vous l'avez déjà avec des Annotations - méta-Annotations. Si vous annoter une annotation avec des méta-données, qui est à bien des égards l'équivalent d'étendre une interface supplémentaire. Les Annotations sont des interfaces, de sorte que le polymorphisme n'a pas vraiment d'entrer en jeu, et depuis ils sont statiques dans la nature, il ne peut y avoir d'exécution dynamique de l'expédition.

Dans votre programme de validation d'exemple, vous pourriez juste sur l'annotation obtenir le annoté type et voir si elle a un programme de validation de la méta-annotation.

Le seul cas d'utilisation j'ai pu voir que l'héritage serait de l'aide est si vous voulez être en mesure d'obtenir l'annotation par des super-type, mais qui permettrait d'ajouter tout un tas de complexité, car une certaine méthode ou le type peut avoir deux annotations sur elle, ce qui signifie qu'un tableau devront être retournés au lieu d'un seul objet.

Donc, je pense que la réponse ultime, c'est que les cas d'utilisation sont ésotériques et de compliquer les plus standard des cas d'utilisation, il n'est pas la peine.

5voto

Les concepteurs de Java annotation soutien apporté un certain nombre de "simplifications" au détriment de la communauté Java.

  1. Pas d'annotations sous-types permet de nombreuses annotations complexes inutilement laid. Il ne suffit pas d'avoir un attribut dans un des annotations qui peut contenir l'une des trois choses. On a besoin d'avoir trois attributs, qui confond les développeurs et nécessite la validation d'exécution pour s'assurer que seul l'un des trois est utilisé.

  2. Seule l'annotation d'un type donné par le site. Cela a conduit à l'complètement inutile collection annotation modèle. @Validation et @Validations, @Image et @Images, etc.

Le second est remédié dans Java 8, mais c'est trop tard. De nombreux cadres ont été rédigé sur la base de ce qui était possible en Java 5 et maintenant, ces API verrues sont ici pour rester pour un long moment.

2voto

denis.zhdanov Points 1669

Jamais pensé à cela mais ... semble que vous avez raison, il n'y a pas de problème avec les annotations héritage facilité (au moins, je ne vois pas le problème avec elle).

A propos de votre exemple avec l' annotation 'validator' - vous pouvez alors exploiter l' approche 'meta-annotation' . C'est-à-dire que vous appliquez des méta-annotations particulières à toute l'interface d'annotation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X