În 2005, odată cu apariția Java 5, am făcut cunoștință cu noi entități numite adnotări.

Adnotările sunt o formă specială de metadate sintactice care pot fi declarate în cod. Ele sunt folosite pentru a analiza codul la compilare sau la runtime. Vă puteți gândi la o adnotare ca la o etichetă, o etichetă sau un indiciu al compilatorului.

Probabil ați mai întâlnit adnotări. De exemplu, când suprascriem o metodă a clasei părinte, scriem @Override înaintea metodei în sine. Această adnotare indică faptul că metoda părintelui va fi suprascrisă în clasa copil.

Sintaxă:


@Override
public int hashCode() {
      return super.hashCode();
}

Vreau să observ imediat că adnotările nu se aplică numai metodelor. Sunt folosite cu pachete, clase, metode, câmpuri și parametri.

Pentru a înțelege cum funcționează adnotările, să ne familiarizăm mai întâi cu conceptul de interfață de marcare. De la apariția Java, dezvoltatorii au avut întotdeauna nevoie de o modalitate de a marca clasele pentru a efectua anumite acțiuni asupra lor.

Înainte de Java 5, ei foloseau o interfață care nu făcea ceea ce ne așteptăm ca interfețele să facă. Nu avea metode și nici contract. Pur și simplu a marcat o clasă ca fiind specială într-un fel.

O astfel de interfață a fost numită interfață marker. După nume ați putea ghici că scopul său este de a marca clase pentru JVM, compilator sau vreo bibliotecă. Unele interfețe de marcare, cum ar fi Serializable , rămân. Această interfață de marcare ne permite să indicăm că instanțele unei clase pot fi serializate.

După cum am văzut, interfețele de marcare continuă să trăiască chiar și după introducerea adnotărilor.

Adnotări versus interfețe de marcare:


@MyAnnotation
public class MyClass {}

public class MyClass implements MarkerInterface {}

Ambele abordări au același obiectiv, dar există o diferență clară în implementarea lor. De exemplu, luați în considerare o interfață și o adnotare care indică faptul că o clasă aparține unui anumit tip.

Dacă folosim o interfață, atunci marchem clasa. Dacă îl folosim incorect și apare o eroare, atunci vom descoperi problema la compilare și programul nu va rula.

Cu adnotări, totul nu este atât de simplu: aici eroarea va fi detectată în timpul execuției, ceea ce înseamnă că programul va porni, dar, fără a fi surprinzător, nu se va termina.

Rețineți că, dacă trebuie să marchem o clasă pentru utilizare ulterioară, instanțele acesteia trebuie să fie transmise unei anumite metode:


public class MyInteger implements Sum {}
interface Sum {};

public static void main(String[] args) throws IOException {
        increase(new MyInteger());
}
 
public static void increase(Sum count) {
        // TODO
}

O interfață de marcare funcționează cel mai bine aici.

Cel mai bine este să folosim adnotările atunci când avem nevoie de ceva mai mult, cum ar fi parametrii pe care îi acceptă adnotările.

Să ne uităm la adnotările standard din JDK:

Adnotare Descriere Exemplu
@Trece peste Specifică faptul că o metodă suprascrie metoda unei superclase sau implementează o metodă a unei clase sau interfețe abstracte.

@Override
public int hashCode() {
        return super.hashCode();
}
@Depreciat Marchează codul ca fiind depreciat.

@Deprecated
public abstract void method();
@SuppressWarnings Dezactivează avertismentele compilatorului pentru elementul adnotat. Rețineți că, dacă trebuie să dezactivați mai multe categorii de avertismente, acestea trebuie să fie incluse între acolade, de exemplu @SuppressWarnings({"unchecked", "cast"}) .

public class DocumentsFolder {
   private List documents;

   @SuppressWarnings("unchecked")
public void addDocument(String document) {
            documents.add(document);
   }
}

În acest exemplu, încercăm să adăugăm la o listă care nu are un tip definit (un tip generic). Compilatorul ne va avertiza despre acest lucru. Acest lucru este foarte util, dar uneori sunt prea multe „avertismente” și pot fi zgomotoase. Puteți utiliza această adnotare a metodei și puteți specifica un tip de avertizare a compilatorului ca argument. Există o mulțime de markeri, așa că nu vă faceți griji să le amintiți pe toate - IDEA vă va spune de obicei pe care să adăugați.

Un alt exemplu cu mai multe argumente:


@SuppressWarnings({"unchecked", "deprecated"})