Crearea adnotărilor este un proces destul de simplu, deși este limitat de unele reguli. Acum trebuie să ne dăm seama ce scop practic servesc.

Să ne amintim cum ne creăm propria adnotare.

Vom scrie o adnotare care este pentru clase și metode și care conține informații despre autorul și versiunea codului:

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

Iată clasele noastre pe care le-am adnotat:

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

Cum putem folosi aceste date în timpul execuției?

Folosind reflectarea pentru a extrage metadate din adnotări. Amintiți-vă ce este reflecția. Reflecția este un mecanism de examinare a datelor despre un program în timpul execuției. Reflection vă permite să obțineți informații despre câmpuri, metode, constructori de clase și clase.

Vom folosi reflecția pentru a citi adnotările dintr-o clasă și pentru a afișa informațiile pe care le dorim.

Vom citi datele din clasele noastre în metoda principală :

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

Trecem o instanță a clasei noastre metodei readMyClass .

Apoi putem trece o clasă precum și o metodă metodei readAnnotation . Să facem asta — vom trece un obiect Class și un obiect Method. Este nevoie de un obiect care implementează interfața AnnotatedElement . Acest lucru ne permite să obținem o listă de adnotări de la obiect și să obținem informații despre fiecare dintre ele.

Rețineți că obținem informații numai după ce verificăm dacă adnotarea aparține tipului nostru de adnotare: if (annotation instanceof Info) .

Ieșirea programului ne oferă informații complete din adnotări:

Clasa: annotation.MyClass1
Căutați adnotări în java.lang.Class Autor: Versiunea
autorului : 0.0 Căutați adnotări în java.lang.reflect.Method Autor: Versiunea autorului: 0.0 Clasa: annotation.MyClass2 Căutați adnotări în java.lang. Clasa Autor: Autor Versiune: 2.0 Căutați adnotări în java.lang.reflect.Method Autor: Anonymous Versiunea: 0.0 Clasă: annotation.MyClass3 Căutați adnotări în java.lang.Class Autor: Anonymous Versiunea: 2.0 Căutați adnotări în java. lang.reflect.Metodă Autor: Anonim Versiunea: 4.0



















Astfel, cu ajutorul reflecției, am putut extrage metadatele.

Acum să ne uităm la un exemplu de utilizare a adnotărilor pentru a îmbunătăți codul, inclusiv creșterea lizibilității, vitezei și calității în general. Lombok ne va ajuta cu asta.

Lombok este un plugin de compilare care folosește adnotări pentru a ascunde o cantitate imensă de cod și pentru a extinde limbajul, simplificând astfel dezvoltarea și adăugând unele funcționalități.

Luați în considerare un exemplu de adnotări din Lombok:

@ToString Generează o implementare a metodei toString() care constă într-o reprezentare detaliată a obiectului: numele clasei, toate câmpurile și valorile acestora.
@ToString
public class Example
@EqualsAndHashCode Generează implementări de equals și hashCode care utilizează câmpuri non-statice și non-statice în mod implicit, dar sunt configurabile. Mai multe detalii găsiți pe site-ul proiectului . Acolo veți găsi un exemplu care folosește @EqualsAndHashCode și arată, de asemenea, o implementare standard fără adnotare.
@Getter / @Setter Generează getter și setter pentru câmpuri private.
@Getter
@Setter
private String name = "name";
@NonNull Folosit pentru a afirma că câmpurile nu sunt nule atunci când un obiect este instanțiat. În caz contrar, este aruncată o excepție NullPointerException .
public Example(@NonNull P p) {
 super("Hello");
 this.name = p.getName();
}

Lombok are multe mai multe adnotări utile care sunt folosite mai rar. Am luat în considerare cele mai simple adnotări ale sale. Puteți citi mai multe despre proiect pe site-ul oficial .