La création d'annotations est un processus assez simple, bien qu'il soit limité par certaines règles. Maintenant, nous devons déterminer à quoi ils servent concrètement.

Rappelons comment nous créons notre propre annotation.

Nous allons écrire 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";
}

Voici nos cours que nous avons annotés :


@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() {}
}

Comment pouvons-nous utiliser ces données lors de l'exécution ?

En utilisant la réflexion pour extraire les métadonnées des annotations. Rappelez-vous ce qu'est la réflexion. La réflexion est un mécanisme permettant d'examiner les données d'un programme au moment de l'exécution. La réflexion vous permet d'obtenir des informations sur les champs, les méthodes, les constructeurs de classe et les classes.

Nous utiliserons la réflexion pour lire les annotations d'une classe et afficher les informations souhaitées.

Nous lirons les données de nos classes dans la méthode principale :


import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
 
public class Main {
   public static void main(String[] args) throws NoSuchMethodException {
       readMyClass(MyClass1.class);
       readMyClass(MyClass2.class);
       readMyClass(MyClass3.class);
   }
 
   static void readMyClass(Class<?> myClassObj) throws NoSuchMethodException {
       System.out.println("\nClass: " + myClassObj.getName());
       readAnnotation(myClassObj);
       Method method = myClassObj.getMethod("myClassMethod");
       readAnnotation(method);
   }
 
   static void readAnnotation(AnnotatedElement element) {
       try {
           System.out.println("Search for annotations in " + element.getClass().getName());
           Annotation[] annotations = element.getAnnotations();
           for (Annotation annotation : annotations) {
               if (annotation instanceof Info) {
                   final Info fileInfo = (Info) annotation;
                   System.out.println("Author: " + fileInfo.author());
                   System.out.println("Version: " + fileInfo.version());
               }
           }
       } catch (Exception e) {
           e.printStackTrace();
       }
   }
}

Nous passons une instance de notre classe à la méthode readMyClass .

Ensuite, nous pouvons passer une classe ainsi qu'une méthode à la méthode readAnnotation . Faisons cela — nous allons passer un objet Class et un objet Method. Il prend un objet qui implémente l' interface AnnotatedElement . Cela nous permet d'obtenir une liste d'annotations de l'objet et d'obtenir des informations sur chacune d'elles.

Notez que nous n'obtenons des informations qu'après avoir vérifié si l'annotation appartient à notre type d'annotation : if (annotation instanceof Info) .

La sortie du programme nous donne des informations complètes à partir des annotations :

Classe : annotation.MyClass1
Recherche d'annotations dans java.lang.Class
Auteur : Author
Version : 0.0
Recherche d'annotations dans java.lang.reflect.Method
Auteur : Author
Version : 0.0

Classe : annotation.MyClass2
Recherche d'annotations dans java.lang. Classe
Auteur : Author
Version : 2.0
Rechercher des annotations dans java.lang.reflect.Method
Auteur : Anonymous
Version : 0.0

Classe : annotation.MyClass3
Rechercher des annotations dans java.lang.Class
Auteur : Anonymous
Version : 2.0
Rechercher des annotations dans java. lang.reflect.Method
Auteur : Anonyme
Version : 4.0

Ainsi, à l'aide de la réflexion, nous avons pu extraire les métadonnées.

Examinons maintenant un exemple d'utilisation d'annotations pour améliorer le code, notamment en augmentant la lisibilité, la vitesse et la qualité en général. Lombok nous y aidera.

Lombok est un plugin de compilateur qui utilise des annotations pour masquer une énorme quantité de code et étendre le langage, simplifiant ainsi le développement et ajoutant certaines fonctionnalités.

Prenons un exemple d'annotations de Lombok :

@ToString Génère une implémentation de la méthode toString() qui consiste en une représentation complète de l'objet : le nom de la classe, tous les champs et leurs valeurs.

@ToString
public class Example
@EqualsAndHashCode Génère des implémentations de equals et hashCode qui utilisent des champs non statiques et non statiques par défaut, mais qui sont configurables. Plus de détails peuvent être trouvés sur le site web du projet . Vous y trouverez un exemple qui utilise @EqualsAndHashCode et montre également une implémentation standard sans l'annotation.
@Getter / @Setter Génère des getters et des setters pour les champs privés.

@Getter 
@Setter 
private String name = "name";
@NonNull Utilisé pour affirmer que les champs ne sont pas nuls lorsqu'un objet est instancié. Sinon, une NullPointerException est levée.

public Example(@NonNull P p) {
 super("Hello");
 this.name = p.getName();
}

Lombok a beaucoup plus d'annotations utiles qui sont utilisées moins souvent. Nous avons considéré ses annotations les plus simples. Vous pouvez en savoir plus sur le projet sur le site officiel .