English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
In questa guida, impareremo diversi tipi di annotazioni Java con esempi.
Le annotazioni Java sono i metadati del nostro codice sorgente (dati sui dati). Java SE fornisce alcune annotazioni predefinite. Inoltre, possiamo creare annotazioni personalizzate secondo necessità.
Se non sai cosa sono le annotazioni, visitaAnnotazioni JavaGuida.
Queste annotazioni possono essere classificate come:
1. Annotazioni predefinite
@Deprecated
@Override
@SuppressWarnings
@SafeVarargs
@FunctionalInterface
2. Annotazioni personalizzate
3. Annotazioni meta
@Retention
@Documented
@Target
@Inherited
@Repeatable
L'annotazione @Deprecated è un'annotazione di segno che indica che l'elemento (classe, metodo, campo, ecc.) è obsoleto e sostituito da un elemento aggiornato.
La sua sintassi è:
@Deprecated accessModifier returnType deprecatedMethodName() { ... }
Quando il programma utilizza elementi dichiarati come dismessi, il compilatore genera un avviso.
Usiamo il segno @deprecated di Javadoc per registrare gli elementi dismessi.
/** * @deprecated * Perché è stato dismesso */ @Deprecated accessModifier returnType deprecatedMethodName() { ... }
class Main { /** * @deprecated * Questo metodo è stato dismesso e sostituito da newMethod(). */ @Deprecated public static void deprecatedMethod() { System.out.println("Metodo deprecato"); } public static void main(String args[]) { deprecatedMethod(); } }
Risultato di output
Metodo deprecato
@Override annotazione specifica che il metodo della sottoclasse deve avere lo stesso nome, tipo di ritorno e elenco dei parametri dell'override del metodo della superclasse.
@Override non è obbligatorio quando si ridefinisce un metodo. Ma se viene utilizzato, se si verifica un errore (ad esempio un tipo di parametro errato) durante la sovrascrittura del metodo, il compilatore fornirà un errore.
class Animal { //Ridefinisci il metodo public void display(){ System.out.println("Io sono un animale"); } } class Dog extends Animal { //Ridefinisci il metodo @Override public void display(){ System.out.println("Io sono un cane"); } public void printMessage(){ display(); } } class Main { public static void main(String[] args) { Dog dog1 = new Dog(); dog1.printMessage(); } }
Risultato di output
Io sono un cane
In questo esempio, creando un oggetto della classe Dog chiamato dog1, possiamo chiamare il suo metodo printMessage(), che esegue quindi la statement display().
Poiché il metodo display() è definito in entrambi i classi, il metodo display() della sottoclasse Dog sovrascrive il metodo display() della superclasse Animal. Di conseguenza, viene chiamato il metodo della sottoclasse.
Come suggerisce il nome, l'annotazione @SuppressWarnings indica al compilatore di disabilitare gli avvisi generati durante l'esecuzione del programma.
Possiamo specificare il tipo di avviso da annullare. Gli avvisi che possono essere disabilitati sono specifici del compilatore, ma gli avvisi sono divisi in due categorie:Disabilitato e Non verificato.
Per disabilitare la visualizzazione di avvisi di categorie specifiche, utilizziamo intenzionalmente:
@SuppressWarnings("warningCategory")
Ad esempio:
@SuppressWarnings("deprecated")
Per disabilitare la visualizzazione di più categorie di avvisi, utilizziamo intenzionalmente:
@SuppressWarnings({"warningCategory1", "warningCategory2"})
Ad esempio:
@SuppressWarnings({"deprecated", "unchecked"})
Quando utilizziamo elementi non raccomandati, la category deprecated indica al compilatore di disabilitare gli avvisi.
Quando utilizziamo i tipi primitivi, l'indicazione unchecked category indica al compilatore di disabilitare gli avvisi.
Ecco un esempio, l'avviso non definito viene ignorato.
@SuppressWarnings("someundefinedwarning")
class Main { @Deprecated public static void deprecatedMethod() { System.out.println("Metodo deprecato"); } @SuppressWarnings("deprecated") public static void main(String args[]) { Main depObj = new Main(); depObj.deprecatedMethod(); } }
Risultato di output
Metodo deprecato
In questo esempio, deprecatedMethod() è stato etichettato come deprecato e l'uso genera un avviso del compilatore. Utilizzando l'annotazione @SuppressWarnings("deprecated") possiamo evitare l'avviso del compilatore.
L'annotazione @SafeVarargs afferma che il metodo o il costruttore annotato non esegue operazioni non sicure sui suoi parametri variabili (numero variabile di parametri).
Possiamo usare questa annotazione solo nei metodi o costruttori non sovrascrivibili. Questo è perché sovrascrivere loro può eseguire operazioni non sicure.
Prima di Java 9, potevamo utilizzare questa annotazione solo nei metodi final o statici, perché non potevano essere sovrascritti. Ora, possiamo anche usarla nei metodi privati.
import java.util.*; class Main { private void displayList(List<String>... lists) { for (List<String> list : lists) { System.out.println(list); } } public static void main(String args[]) { Main obj = new Main(); List<String> universityList = Arrays.asList("Università Tribhuvan", "Università di Kathmandu"); obj.displayList(universityList); List<String> programmazioneLinguistica = Arrays.asList("Java", "C"); obj.displayList(universityList, programmazioneLinguistica); } }
Avvisi
Sicurezza del tipo: Inquinamento potenziale della pila tramite liste parametriche varargs Sicurezza del tipo: Viene creato un array generico di List<String> per un varargs parametro
Risultato di output
Nota: Main.java utilizza operazioni non verificate o non sicure. [Università Tribhuvan, Università di Kathmandu] [Università Tribhuvan, Università di Kathmandu] [Java, C]
In questo caso, List ... list specifica un tipo di variabili lunghe List. Questo significa che il metodo displayList() può avere zero o più parametri.
Il programma sopra compila senza errori, ma emette avvisi quando non si utilizza l'annotazione @SafeVarargs.
Quando si utilizza l'annotazione @SafeVarargs nell'esempio sopra,
@SafeVarargs private void displayList(List<String>... lists) { ... }
Riceviamo lo stesso output ma senza avvisi. Quando si utilizza questa annotazione, anche gli avvisi non verificati vengono eliminati.
Java 8 ha introdotto questa annotazione @FunctionalInterface. Questa annotazione indica che il tipo dichiarato utilizza questa annotazione è un'interfaccia funzionale. Un'interfaccia funzionale può avere solo un metodo astratto.
@FunctionalInterface public interface MyFuncInterface{ public void firstMethod(); // Questo è un metodo astratto }
Se aggiungiamo un altro metodo astratto, allora
@FunctionalInterface public interface MyFuncInterface{ public void firstMethod(); // Questo è un metodo astratto public void secondMethod(); // Questo genererà un errore di compilazione }
Ora, quando eseguiamo il programma, riceveremo i seguenti avvisi:
Annotatione @FunctionalInterface inattesa @FunctionalInterface ^ MyFuncInterface non è un'interfaccia funzionale Trovati molti metodi astratti non sovrascrivibili nell'interfaccia MyFuncInterface
L'uso dell'annotazione @FunctionalInterface non è obbligatorio. Il compilatore considererà qualsiasi interfaccia che soddisfi la definizione dell'interfaccia funzionale come interfaccia funzionale.
Il nostro obiettivo con questa annotazione è garantire che l'interfaccia funzionale abbia solo un metodo astratto.
Ma può avere un numero illimitato di metodi di default e statici, perché hanno un'implementazione.
@FunctionalInterface public interface MyFuncInterface{ public void firstMethod(); // È un metodo astratto default void secondMethod() { ... } default void thirdMethod() { ... } }
Puoi anche creare le nostre annotazioni personalizzate.
La sua sintassi è:
[Specificadori di accesso] @interface<NomeAnnotazione> { DataType <MethodName>() [valore predefinito]; }
Ecco l'informazione che devi sapere sulle annotazioni personalizzate:
Le annotazioni possono essere create utilizzando @interface seguito dal nome dell'annotazione.
Le annotazioni possono avere elementi che sembrano metodi, ma non hanno un'implementazione.
Il valore predefinito è opzionale. I parametri non possono essere valori nulli.
Il tipo di ritorno del metodo può essere primitivo, enum, stringa, nome della classe o un array di questi tipi.
@interface MyCustomAnnotation { String value() default "default value"; } class Main { @MyCustomAnnotation(value = "w3codebox") public void method1() { System.out.println("Test metodo 1"); } public static void main(String[] args) throws Exception { Main obj = new Main(); obj.method1(); } }
Risultato di output
Test metodo 1
Le annotazioni meta sono annotazioni applicate ad altre annotazioni.
L'annotazione @Retention specifica il livello massimo di disponibilità dell'annotazione.
La sua sintassi è:
@Retention(RetentionPolicy)
Ci sono tre tipi:
RetentionPolicy.SOURCE - Le annotazioni sono disponibili solo al livello di origine e vengono ignorate dal compilatore.
RetentionPolicy.CLASS - Le annotazioni sono disponibili per il compilatore durante la compilazione, ma il Java Virtual Machine (JVM) le ignora.
RetentionPolicy.RUNTIME - Le annotazioni possono essere utilizzate nel JVM.
Ad esempio:
@Retention(RetentionPolicy.RUNTIME) public @interface MyCustomAnnotation{ ... }
Di default, le annotazioni personalizzate non sono incluse nella documentazione ufficiale di Java. Per includere l'annotazione nella documentazione Javadoc, utilizzare l'annotazione @Documented.
Ad esempio:
@Documented public @interface MyCustomAnnotation{ ... }
Possiamo utilizzare l'annotazione @Target per limitare l'annotazione all'applicazione a un obiettivo specifico.
La sua sintassi è:
@Target(ElementType)
ElementType può essere uno dei seguenti tipi:
Tipo di elemento | Target |
---|---|
ElementType.ANNOTATION_TYPE | Tipo di annotazione |
ElementType.CONSTRUCTOR | Costruttore |
ElementType.FIELD | Campo |
ElementType.LOCAL_VARIABLE | Variabile locale |
ElementType.METHOD | Metodo |
ElementType.PACKAGE | Pacchetto |
ElementType.PARAMETER | Parametro |
ElementType.TYPE | Usato per descrivere dichiarazioni di classe, interfaccia (inclusi i tipi di annotazione) o enum. |
Ad esempio:
@Target(ElementType.METHOD) public @interface MyCustomAnnotation{ ... }
In questo esempio, limitiamo l'uso di questa annotazione ai metodi.
Attenzione:Se non viene definito il tipo di destinazione, l'annotazione può essere utilizzata per qualsiasi elemento.
Di default, il tipo di annotazione non può essere ereditato dalla superclasse. Ma se è necessario ereditare l'annotazione dalla superclasse alla sottoclasse, si può utilizzare l'annotazione @Inherited.
La sua sintassi è:
@Inherited
Ad esempio:
@Inherited public @interface MyCustomAnnotation { ... } @MyCustomAnnotation public class ParentClass{ ... } public class ChildClass extends ParentClass { ... }
Le annotazioni marcate con @Repeatable possono essere applicate più volte allo stesso dichiarativo.
@Repeatable(Universities.class) public @interface University { String name(); }
Il valore definito dall'annotazione @Repeatable è un'annotazione contenitore. Le annotazioni contenitrici hanno il valore del tipo dell'array di annotazioni ripetibili (value). In questo caso, Universities è il contenitore degli tipi di annotazione.
public @interface Universities { University[] value(); }
Ora, l'annotazione @University può essere utilizzata più volte sulla stessa dichiarazione.
@University(name = "TU") @University(name = "KU") private String uniName;
Se si desidera cercare i dati degli annotazioni, è possibile utilizzareRiflessione.
Per cercare i valori degli annotazioni, utilizziamo i metodi getAnnotationsByType() o getAnnotations() definiti nell'API di riflessione.