Annotaties maken is een vrij eenvoudig proces, hoewel het wordt beperkt door enkele regels. Nu moeten we uitzoeken welk praktisch doel ze dienen.

Laten we onthouden hoe we onze eigen annotatie maken.

We zullen een annotatie schrijven voor klassen en methoden en informatie bevatten over de auteur en versie van de code:


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

Dit zijn onze klassen die we hebben geannoteerd:


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

Hoe kunnen we deze gegevens tijdens runtime gebruiken?

Door reflectie te gebruiken om metadata uit annotaties te halen. Bedenk wat reflectie is. Reflectie is een mechanisme voor het onderzoeken van gegevens over een programma tijdens runtime. Reflectie geeft u informatie over velden, methoden, klassenconstructeurs en klassen.

We gebruiken reflectie om de annotaties in een klas te lezen en de gewenste informatie weer te geven.

We lezen gegevens uit onze klassen in de hoofdmethode :


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

We geven een instantie van onze klasse door aan de methode readMyClass .

Dan kunnen we zowel een klasse als een methode doorgeven aan de methode readAnnotation . Laten we dat doen - we geven een Class-object en een Method-object door. Er is een object voor nodig dat de AnnotatedElement- interface implementeert. Hierdoor kunnen we een lijst met annotaties van het object krijgen en informatie over elk ervan krijgen.

Merk op dat we alleen informatie krijgen nadat we hebben gecontroleerd of de annotatie tot ons annotatietype behoort: if (annotation instanceof Info) .

De programma-uitvoer geeft ons volledige informatie uit de annotaties:

Klasse: annotation.MyClass1
Zoek naar annotaties in java.lang.Class
Auteur: Auteur
Versie: 0.0
Zoek naar annotaties in java.lang.reflect.Method
Auteur: Auteur
Versie: 0.0

Klasse: annotation.MyClass2
Zoek naar annotaties in java.lang. Klasse
Auteur: Auteur
Versie: 2.0
Zoek naar annotaties in java.lang.reflect.Method
Auteur: Anoniem
Versie: 0.0

Klasse: annotation.MyClass3
Zoek naar annotaties in java.lang.Class
Auteur: Anoniem
Versie: 2.0
Zoek naar annotaties in java. lang.reflect.Method
Auteur: anoniem
Versie: 4.0

Zo konden we met behulp van reflectie de metadata extraheren.

Laten we nu eens kijken naar een voorbeeld van het gebruik van annotaties om code te verbeteren, inclusief het verbeteren van de leesbaarheid, snelheid en kwaliteit in het algemeen. Lombok zal ons hierbij helpen.

Lombok is een compiler-plug-in die annotaties gebruikt om een ​​enorme hoeveelheid code te verbergen en de taal uit te breiden, waardoor de ontwikkeling wordt vereenvoudigd en wat functionaliteit wordt toegevoegd.

Overweeg een voorbeeld van annotaties uit Lombok:

@ToString Genereert een implementatie van de methode toString() die bestaat uit een grondige weergave van het object: de klassenaam, alle velden en hun waarden.

@ToString
public class Example
@EqualsAndHashCode Genereert implementaties van equals en hashCode die standaard niet-statische en niet-statische velden gebruiken, maar die configureerbaar zijn. Meer details zijn te vinden op de website van het project . Daar vindt u een voorbeeld dat @EqualsAndHashCode gebruikt en ook een standaardimplementatie laat zien zonder de annotatie.
@Getter / @Setter Genereert getters en setters voor privévelden.

@Getter 
@Setter 
private String name = "name";
@NonNull Wordt gebruikt om te bevestigen dat velden niet null zijn wanneer een object wordt geïnstantieerd. Anders wordt een NullPointerException gegenereerd.

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

Lombok heeft nog veel meer handige annotaties die minder vaak gebruikt worden. We hebben de eenvoudigste annotaties overwogen. U kunt meer lezen over het project op de officiële website .