Le principal avantage des annotations ne vient pas de l'utilisation des annotations standard déjà présentes dans le JDK. Dans le même temps, il est rarement nécessaire de créer votre propre annotation. Mais si nous développons un grand système ou créons une bibliothèque séparée, alors au niveau architectural, la mise en œuvre de notre propre annotation rapportera certainement des dividendes.

Essayons de créer une annotation.

Pour ce faire, créez un fichier, mais au lieu d'écrire class ou interface , écrivez @interface . Ce sera le fichier pour notre annotation. La structure interne d'une annotation est similaire à celle d'une interface.

public @interface Sum {
   int sum() default 0;
}

@interface indique qu'il s'agit d'une annotation,
default indique que le paramètre aura une valeur par défaut spécifique.

Ta-da ! Nous avons créé une annotation ! Théoriquement, nous pouvons déjà l'utiliser, mais il serait préférable de le configurer d'abord.

Sans configuration, notre annotation peut être appliquée à n'importe quoi (aux classes, aux méthodes, aux attributs, etc.), il n'est donc pas logique de l'utiliser à ce stade. Aussi étrange que cela puisse paraître, notre annotation doit être annotée avec d'autres annotations !

Commençons par @Target .

L' annotation @Target (pertinente depuis Java 1.5) limite la possibilité d'appliquer une annotation. Pour limiter l'utilisation à un certain niveau, nous devons passer un argument à l' annotation @Target pour indiquer à quels types elle peut être appliquée. Voici quelques-uns des types couramment utilisés :

@Target(TypeElement.PACKAGE) pour les colis
@Target(TypeElement.TYPE) pour les cours
@Target(ElementType.CONSTRUCTEUR) pour les constructeurs
@Target(ElementType.METHOD) pour les méthodes
@Target(TypeÉlément.CHAMP) pour les attributs (variables) d'une classe
@Target(ElementType.PARAMATER) pour les paramètres de méthode
@Target(TypeElement.LOCAL_VARIABLE) pour les variables locales

Si vous avez besoin d'une annotation pour plusieurs types, vous pouvez passer plusieurs arguments sous forme de tableau :

@Target({ ElementType.PARAMETER, ElementType.LOCAL_VARIABLE })

La prochaine partie importante de la configuration est l' annotation @Retention .

Cette annotation indique les parties du cycle de vie du code dans lesquelles notre annotation sera disponible :

RetentionPolicy.SOURCE Les annotations marquées avec la stratégie de rétention SOURCE sont supprimées au moment de l'exécution.
RetentionPolicy.CLASS Les annotations marquées avec la stratégie de rétention CLASS sont écrites dans le fichier .class , mais sont supprimées au moment de l'exécution.
RetentionPolicy.RUNTIME Les annotations marquées avec la politique de rétention RUNTIME persistent au moment de l'exécution et sont accessibles dans notre programme au moment de l'exécution.

Il existe quelques annotations supplémentaires que vous pouvez utiliser pour la configuration :

Annotation Valeur
@Hérité Indique qu'une classe dérivée hérite de l'implémentation d'une classe parent de l'annotation.
@Documenté Cela indique que l'annotation sera incluse dans la documentation Javadoc générée.

Essayons maintenant de créer notre propre annotation.

Nous allons créer une annotation destinée aux classes et aux méthodes et contenant des informations sur l'auteur et la version du code :

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Info {
   String author() default "Author";
   String version() default "0.0";
}

Nous pouvons appliquer notre annotation aux méthodes et aux classes. Les métadonnées de nos annotations seront disponibles au moment de l'exécution. Faites attention aux paramètres de notre annotation : nous pouvons fournir deux arguments (auteur et version), ou nous pouvons les omettre. Si nous les omettons, les valeurs par défaut spécifiées ( "Auteur" par défaut et "0.0" par défaut ) seront utilisées.

Il convient de noter que nous n'avons pas à spécifier de valeur par défaut pour les paramètres. Dans ce cas, le paramètre devient obligatoire.

Lors du passage des arguments, nous devons spécifier le paramètre correspondant en utilisant la notation value = "value" . Le paramètre doit toujours être nommé explicitement, même si l'annotation a un seul paramètre.

Appliquons notre annotation à quelques classes :

@Info
public class MyClass1 {
   @Info
   public void myClassMethod() {}
}

@Info(version = "2.0")
public class MyClass2 {
   @Info(author = "Anonymous")
   public void myClassMethod() {}
}

@Info(author = "Anonymous", version = "2.0")
public class MyClass3 {
   @Info(author = "Anonymous", version = "4.0")
   public void myClassMethod() {}
}