La creazione di annotazioni è un processo abbastanza semplice, sebbene sia limitato da alcune regole. Ora dobbiamo capire a quale scopo pratico servono.
Ricordiamo come creiamo la nostra annotazione.
Scriveremo un'annotazione per classi e metodi e conterrà informazioni sull'autore e la versione del codice:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Info {
String author() default "Author";
String version() default "0.0";
}
Ecco le nostre classi che abbiamo annotato:
@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() {}
}
Come possiamo utilizzare questi dati in fase di esecuzione?
Utilizzando la riflessione per estrarre i metadati dalle annotazioni. Ricorda cos'è la riflessione. La riflessione è un meccanismo per esaminare i dati su un programma in fase di esecuzione. Reflection consente di ottenere informazioni su campi, metodi, costruttori di classi e classi.
Useremo la riflessione per leggere le annotazioni in una classe e visualizzare le informazioni che vogliamo.
Leggeremo i dati dalle nostre classi nel metodo 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();
}
}
}
Passiamo un'istanza della nostra classe al metodo readMyClass .
Quindi possiamo passare una classe e un metodo al metodo readAnnotation . Facciamolo: passeremo un oggetto Class e un oggetto Method. Prende un oggetto che implementa l' interfaccia AnnotatedElement . Questo ci consente di ottenere un elenco di annotazioni dall'oggetto e ottenere informazioni su ciascuna di esse.
Si noti che otteniamo informazioni solo dopo aver verificato se l'annotazione appartiene al nostro tipo di annotazione: if (annotation instanceof Info) .
L'output del programma ci fornisce informazioni complete dalle annotazioni:
Cerca annotazioni in java.lang.Class
Autore: Author
Versione: 0.0
Cerca annotazioni in java.lang.reflect.Method
Autore: Author
Versione: 0.0
Classe: annotation.MyClass2
Cerca annotazioni in java.lang. Classe
Autore: Autore
Versione: 2.0
Cerca annotazioni in java.lang.reflect.Method
Autore: Anonimo
Versione: 0.0
Classe: annotation.MyClass3
Cerca annotazioni in java.lang.Class
Autore: Anonimo
Versione: 2.0
Cerca annotazioni in java. lang.reflect.Method
Autore: Anonimo
Versione: 4.0
Così, con l'aiuto della riflessione, siamo stati in grado di estrarre i metadati.
Ora diamo un'occhiata a un esempio di utilizzo delle annotazioni per migliorare il codice, incluso l'aumento della leggibilità, della velocità e della qualità in generale. Lombok ci aiuterà in questo.
Lombok è un plug-in del compilatore che utilizza le annotazioni per nascondere un'enorme quantità di codice ed estendere il linguaggio, semplificando così lo sviluppo e aggiungendo alcune funzionalità.
Considera un esempio di annotazioni da Lombok:
@Accordare | Genera un'implementazione del metodo toString() che consiste in una rappresentazione completa dell'oggetto: il nome della classe, tutti i campi e i relativi valori. |
|
@EqualsAndHashCode | Genera implementazioni di equals e hashCode che utilizzano campi non statici e non statici per impostazione predefinita, ma sono configurabili. | Maggiori dettagli possono essere trovati sul sito web del progetto . Lì troverai un esempio che utilizza @EqualsAndHashCode e mostra anche un'implementazione standard senza l'annotazione. |
@Getter / @Setter | Genera getter e setter per i campi privati. |
|
@NonNull | Utilizzato per affermare che i campi non sono nulli quando viene istanziato un oggetto. In caso contrario, viene generata un'eccezione NullPointerException . |
|
Lombok ha molte più annotazioni utili che vengono usate meno spesso. Abbiamo considerato le sue annotazioni più semplici. Puoi leggere di più sul progetto sul sito ufficiale .
GO TO FULL VERSION