Il vantaggio principale delle annotazioni non deriva dall'utilizzo di quelle standard già presenti nel JDK. Allo stesso tempo, raramente è necessario creare la propria annotazione. Ma se stiamo sviluppando un sistema di grandi dimensioni o creando una libreria separata, a livello di architettura, l'implementazione della nostra annotazione produrrà sicuramente dividendi.

Proviamo a creare un'annotazione.

Per fare ciò, crea un file, ma invece di scrivere class o interface , scrivi @interface . Questo sarà il file per la nostra annotazione. La struttura interna di un'annotazione è simile a quella di un'interfaccia.

public @interface Sum {
   int sum() default 0;
}

@interface indica che si tratta di un'annotazione,
default indica che il parametro avrà un valore predefinito specifico.

Ta-da! Abbiamo creato un'annotazione! Teoricamente possiamo già usarlo, ma prima sarebbe meglio configurarlo.

Senza configurazione, la nostra annotazione può essere applicata a qualsiasi cosa (a classi, metodi, attributi, ecc.), quindi ha poco senso usarla a questo punto. Per quanto strano possa sembrare, la nostra annotazione deve essere annotata con altre annotazioni!

Iniziamo con @Target .

L' annotazione @Target (rilevante da Java 1.5) limita la possibilità di applicare un'annotazione. Per limitare l'utilizzo a un certo livello, dobbiamo passare un argomento all'annotazione @Target per indicare a quali tipi può essere applicato. Ecco alcuni dei tipi comunemente usati:

@Target(ElementType.PACKAGE) per i pacchetti
@Target(ElementType.TYPE) per le classi
@Target(ElementType.CONSTRUCTOR) per i costruttori
@Target(ElementType.METODO) per i metodi
@Target(ElementType.FIELD) per attributi (variabili) in una classe
@Target(ElementType.PARAMATER) per i parametri del metodo
@Target(ElementType.LOCAL_VARIABLE) per le variabili locali

Se hai bisogno di un'annotazione per diversi tipi, puoi passare diversi argomenti come un array:

@Target({ ElementType.PARAMETER, ElementType.LOCAL_VARIABLE })

La prossima parte importante della configurazione è l' annotazione @Retention .

Questa annotazione indica le parti del ciclo di vita del codice in cui sarà disponibile la nostra annotazione:

RetentionPolicy.SOURCE Le annotazioni contrassegnate con il criterio di conservazione SOURCE vengono eliminate in fase di esecuzione.
RetentionPolicy.CLASS Le annotazioni contrassegnate con il criterio di conservazione CLASS vengono scritte nel file .class , ma vengono rimosse in fase di esecuzione.
RetentionPolicy.RUNTIME Le annotazioni contrassegnate con la politica di conservazione RUNTIME persistono in fase di esecuzione e sono accessibili nel nostro programma in fase di esecuzione.

Ci sono alcune altre annotazioni che puoi usare per la configurazione:

Annotazione Valore
@Ereditato Indica che una classe derivata eredita l'implementazione dell'annotazione da una classe padre.
@Documentato Ciò indica che l'annotazione verrà inclusa nella documentazione Javadoc generata.

Ora proviamo a creare la nostra annotazione.

Creeremo 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";
}

Possiamo applicare la nostra annotazione a metodi e classi. I metadati della nostra annotazione saranno disponibili in fase di esecuzione. Presta attenzione ai parametri della nostra annotazione: possiamo fornire due argomenti (autore e versione), oppure possiamo ometterli. Se li omettiamo, verranno utilizzati i valori predefiniti specificati ( default "Author" e default "0.0" ).

Vale la pena notare che non è necessario specificare un valore predefinito per i parametri. In questo caso il parametro diventa obbligatorio.

Quando passiamo argomenti, dobbiamo specificare il parametro corrispondente usando la notazione value = "value" . Il parametro deve essere sempre denominato in modo esplicito, anche se l'annotazione ha un solo parametro.

Applichiamo la nostra annotazione ad alcune classi:

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