English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

教程基础Java

Controllo del flusso Java

Array Java

Orientamento ad oggetti Java (I)

Orientamento ad oggetti Java (II)

Orientamento ad oggetti Java (III)

Gestione delle eccezioni Java

Lista Java

Queue Java (coda)

Map di Java

Set di Java

Input/Output (I/O) Java

Lettore/Scrittore Java

Altri argomenti Java

Tipi di annotazione Java

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

Tipi di annotazione predefiniti

1. @Deprecated

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

Esempio 1: Esempio di annotazione @Deprecated

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

2. @Override

@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.

Esempio 2: Esempio di annotazione @Override

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.

3. @SuppressWarnings

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")

Esempio 3: Esempio di annotazione @SuppressWarnings

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.

4. @SafeVarargs

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.

Esempio 4: Esempio di annotazione @SafeVarargs

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.

5. @FunctionalInterface

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.

Esempio 5: Esempio di annotazione @FunctionalInterface

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

Annotazioni personalizzate

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.

Esempio 6: Esempio di annotazione personalizzata

@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

Annotazioni meta

Le annotazioni meta sono annotazioni applicate ad altre annotazioni.

1. @Retention

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{ ... }

2. @Documented

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{ ... }

3. @Target

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 elementoTarget
ElementType.ANNOTATION_TYPETipo di annotazione
ElementType.CONSTRUCTORCostruttore
ElementType.FIELDCampo
ElementType.LOCAL_VARIABLEVariabile locale
ElementType.METHODMetodo
ElementType.PACKAGEPacchetto
ElementType.PARAMETERParametro
ElementType.TYPEUsato 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.

4. @Inherited

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 { ... }

5. @Repeatable

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.