Oprettelse af annoteringer er en ret simpel proces, selvom den er begrænset af nogle regler. Nu skal vi finde ud af, hvilket praktisk formål de tjener.

Lad os huske, hvordan vi opretter vores egen annotering.

Vi skriver en annotation, der er til klasser og metoder og indeholder oplysninger om kodens forfatter og version:

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

Her er vores klasser, som vi har kommenteret:

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

Hvordan kan vi bruge disse data under runtime?

Ved at bruge refleksion til at udtrække metadata fra annoteringer. Husk hvad refleksion er. Refleksion er en mekanisme til at undersøge data om et program under kørsel. Reflektion lader dig få information om felter, metoder, klassekonstruktører og klasser.

Vi bruger refleksion til at læse annoteringerne i en klasse og vise den information, vi ønsker.

Vi læser data fra vores klasser i hovedmetoden :

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();
       }
   }
}

Vi videregiver en forekomst af vores klasse til readMyClass -metoden.

Så kan vi videregive en klasse såvel som en metode til readAnnotation metoden. Lad os gøre det - vi sender et klasseobjekt og et metodeobjekt. Det tager et objekt, der implementerer AnnotatedElement- grænsefladen. Dette lader os få en liste over annoteringer fra objektet og få information om hver af dem.

Bemærk, at vi først får information efter at have kontrolleret, om annotationen tilhører vores annotationstype: if (annotationsinstans af Info) .

Programoutputtet giver os fuldstændig information fra annoteringerne:

Klasse: annotation.MyClass1
Søg efter annoteringer i java.lang.Class
Forfatter: Forfatter
Version: 0.0
Søg efter annotationer i java.lang.reflect.Method
Forfatter: Forfatter
Version: 0.0

Klasse: annotation.MyClass2
Søg efter annotationer i java.lang. Klasse
Forfatter: Forfatter
Version: 2.0
Søg efter annoteringer i java.lang.reflect.Method
Forfatter: Anonym
Version: 0.0

Klasse: annotation.MyClass3
Søg efter annoteringer i java.lang.Class
Forfatter: Anonym
Version: 2.0
Søg efter annoteringer i java. lang.reflect.Metode
Forfatter: Anonym
Version: 4.0

Således kunne vi ved hjælp af refleksion udtrække metadataene.

Lad os nu se på et eksempel på at bruge annoteringer til at forbedre kode, herunder øge læsbarheden, hastigheden og kvaliteten generelt. Lombok vil hjælpe os med dette.

Lombok er et compiler-plugin, der bruger annoteringer til at skjule en enorm mængde kode og udvide sproget, og derved forenkle udviklingen og tilføje noget funktionalitet.

Overvej et eksempel på annoteringer fra Lombok:

@ToString Genererer en implementering af toString() -metoden, der består af en grundig repræsentation af objektet: klassenavnet, alle felter og deres værdier.
@ToString
public class Example
@EqualsAndHashCode Genererer implementeringer af equals og hashCode , der som standard bruger ikke-statiske og ikke-statiske felter, men som kan konfigureres. Flere detaljer kan findes på projektets hjemmeside . Der vil du finde et eksempel, der bruger @EqualsAndHashCode og også viser en standardimplementering uden annotationen.
@Getter / @Setter Genererer gettere og sættere til private marker.
@Getter
@Setter
private String name = "name";
@NonNull Bruges til at hævde, at felter ikke er null, når et objekt instansieres. Ellers kastes en NullPointerException .
public Example(@NonNull P p) {
 super("Hello");
 this.name = p.getName();
}

Lombok har mange flere nyttige anmærkninger, der bruges sjældnere. Vi har overvejet dens enkleste anmærkninger. Du kan læse mere om projektet på den officielle hjemmeside .