Comment fonctionne @Target (ElementType.ANNOTATION_TYPE)

Les annotations Java sont marquées avec une annotation @Target pour déclarer les éventuels points de jonction pouvant être décorés par cette annotation. Les valeurs TYPE , FIELD , METHOD , etc. de l’énumération ElementType sont claires et simplement compréhensibles.

Question

POURQUOI utiliser la valeur @Target(ANNOTATION_TYPE) ? A quoi servent les annotations annotées? Quelle est leur consortingbution? Donne-moi une explication de comment ça marche et pourquoi je devrais l’utiliser. Un exemple déjà existant et bien connu de son utilisation serait également génial.

Vous pouvez utiliser une annotation annotée pour créer une méta-annotation, par exemple en considérant cette utilisation de @Transactional dans Spring:

 /** * Shortcut and more descriptive "alias" for {@code @Transactional(propagation = Propagation.MANDATORY)}. */ @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Transactional(propagation = Propagation.MANDATORY) public @interface RequiresExistingTransaction { } 

Lorsque vous activez Spring pour traiter l’annotation @Transactional , il recherche les classes et les méthodes qui portent la @Transactional ou toute méta-annotation correspondante (une annotation annotée avec @Transactional ).

Quoi qu’il en soit, ce n’était qu’un exemple concret de l’utilisation d’une annotation annotée. Je suppose que ce sont surtout des frameworks comme Spring où il est judicieux de les utiliser.

Chaque annotation annotée par @Target(ElementType.ANNOTATION_TYPE) est appelée Meta-annotation . Cela signifie que vous pouvez définir vos propres annotations personnalisées, qui sont une fusion de nombreuses annotations combinées en une seule annotation pour créer des composed annotations .

Un bon exemple du monde Android est SsortingngDef

Indique que l’élément Ssortingng annoté représente un type logique et que sa valeur doit être l’une des constantes explicitement nommées.

 @Retention(SOURCE) @Target({ANNOTATION_TYPE}) public @interface SsortingngDef { /** Defines the allowed constants for this element */ Ssortingng[] value() default {}; } //-- @Retention(SOURCE) @SsortingngDef({POWER_SERVICE, WINDOW_SERVICE, LAYOUT_INFLATER_SERVICE}) public @interface ServicesName {} public static final Ssortingng POWER_SERVICE = "power"; public static final Ssortingng WINDOW_SERVICE = "window"; public static final Ssortingng LAYOUT_INFLATER_SERVICE = "layout_inflater"; //-- @SsortingngDef({SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY}) @Retention(RetentionPolicy.SOURCE) public @interface WeekDays {} public static final Ssortingng SUNDAY = "sunday"; public static final Ssortingng MONDAY = "monday"; public static final Ssortingng TUESDAY = "tuesday"; public static final Ssortingng WEDNESDAY = "wednesday"; public static final Ssortingng THURSDAY = "thursday"; public static final Ssortingng FRIDAY = "friday"; public static final Ssortingng SATURDAY = "saturday"; ... public abstract Object getSystemService(@ServicesName Ssortingng serviceName); public abstract Object getDayOfWeek(@WeekDays Ssortingng weekDay); 

L’inspecteur de code traitera @ServicesName et @WeekDays de la même manière que @SsortingngDef . En conséquence, nous pouvons créer autant de SsortingngDef que nécessaire, et remplacer les constantes. @Target(ElementType.ANNOTATION_TYPE) c’est un outil qui permet d’étendre l’utilisation des annotations.

Par exemple, si l’annotation ressemble à

 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface SomeAnnotation { Ssortingng description() default "This is example for class annotation"; } 

le compilateur se complètera dans cette situation

 @SomeAnnotation public class SomeClass { @SomeAnnotation // here it's complaning public void someMethod(){} } 

Si vous changez

 @Target(ElementType.TYPE) 

à

 @Target({ElementType.METHOD, ElementType.TYPE}) 

il ne se plaindra plus.

Les annotations sont essentiellement des métadonnées (informations) supplémentaires qui accompagnent votre code. Il peut être placé à côté des types (Classes, Interfaces), des méthodes et des arguments.

Il est souvent utile pendant la compilation et l’exécution. De nombreuses API populaires telles que Java EE 5+, Spring, AspectJ exploitent les annotations pour la clarté et la cohérence du code.

L’utilisation de l’annotation permet souvent de rendre le code plus lisible, plus facile à comprendre.

Je vous recommande de lire le chapitre des annotations sur le tutoriel Java

Dans le passé, les métadonnées sont souvent données sous forme de fichier XML, et il est difficile pour une personne essayant de comprendre le code de rechercher un fichier de configuration xml différent. La dernière API de servlet Java permet de mapper le servlet simplement en utilisant l’annotation – par opposition au mappage web.xml :

 @WebServlet("/response") public class ResponseServlet extends HttpServlet { // servlet code here... }