2005, med ankomsten av Java 5, lärde vi känna nya enheter som kallas annoteringar.

Anteckningar är en speciell form av syntaktisk metadata som kan deklareras i kod. De används för att analysera kod vid kompilering eller vid körning. Du kan tänka på en anteckning som en etikett, tagg eller kompilatortips.

Du har förmodligen stött på anteckningar tidigare. Till exempel, när vi åsidosätter en metod för den överordnade klassen, skriver vi @Override före själva metoden. Denna anteckning indikerar att förälderns metod kommer att åsidosättas i barnklassen.

Syntax:

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

Jag vill genast notera att anteckningar inte bara gäller metoder. De används med paket, klasser, metoder, fält och parametrar.

För att förstå hur anteckningar fungerar, låt oss först bekanta oss med konceptet med ett markörgränssnitt. Sedan Javas tillkomst har utvecklare alltid behövt ett sätt att markera klasser för att kunna utföra vissa åtgärder på dem.

Före Java 5 använde de ett gränssnitt som inte gjorde vad vi förväntade oss att gränssnitten skulle göra. Den hade inga metoder och inget kontrakt. Det markerade bara en klass som speciell på något sätt.

Ett sådant gränssnitt kallades ett markörgränssnitt. Från namnet kan du gissa att dess syfte är att markera klasser för JVM, kompilatorn eller något bibliotek. Vissa markörgränssnitt, som Serializable , finns kvar. Detta markörgränssnitt låter oss indikera att instanser av en klass kan serialiseras.

Som vi har sett fortsätter markörgränssnitt att leva kvar även efter införandet av annoteringar.

Anteckningar kontra markörgränssnitt:

@MyAnnotation
public class MyClass {}
public class MyClass implements MarkerInterface {}

Båda tillvägagångssätten har samma mål, men det finns en tydlig skillnad i genomförandet. Tänk till exempel på ett gränssnitt och en anteckning som anger att en klass tillhör en viss typ.

Om vi ​​använder ett gränssnitt markerar vi klassen. Om vi ​​använder det felaktigt och ett fel uppstår, kommer vi att upptäcka problemet vid kompileringen och programmet kommer inte att köras.

Med anteckningar är allt inte så enkelt: här kommer felet att upptäckas vid körning, vilket innebär att programmet startar, men föga överraskande kommer det inte att slutföras.

Observera att om vi behöver markera en klass för framtida användning måste dess instanser skickas till en specifik metod:

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
}

Ett markörgränssnitt fungerar bäst här.

Det är bäst att använda kommentarer när vi behöver något mer, till exempel parametrarna som annoteringar stöder.

Låt oss titta på standardkommentarerna i JDK:

Anteckning Beskrivning Exempel
@Åsidosätta Anger att en metod åsidosätter en superklasss metod eller implementerar en metod för en abstrakt klass eller gränssnitt.
@Override
public int hashCode() {
        return super.hashCode();
}
@Föråldrat Markerar koden som utfasad.
@Deprecated
public abstract void method();
@SuppressWarnings Inaktiverar kompilatorvarningar för det kommenterade elementet. Observera att om du behöver inaktivera flera kategorier av varningar måste de vara inneslutna i hängslen, till exempel @SuppressWarnings({"unchecked", "cast"}) .
public class DocumentsFolder {
   private List documents;

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

I det här exemplet försöker vi lägga till en lista som inte har en definierad typ (en generisk typ). Kompilatorn kommer att varna oss om detta. Detta är mycket användbart, men ibland finns det för många "varningar" och de kan vara bullriga. Du kan använda denna metodanteckning och ange en typ av kompilatorvarning som ett argument. Det finns många markörer, så oroa dig inte för att komma ihåg dem alla – IDEA brukar tala om för dig vilken du ska lägga till.

Ett annat exempel med flera argument:

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