Den største fordel ved annoteringer kommer ikke fra at bruge de standard, der allerede er i JDK. Samtidig er der sjældent behov for at lave din egen annotering. Men hvis vi udvikler et stort system eller opretter et separat bibliotek, så vil implementering af vores egen annotering helt sikkert give udbytte på det arkitektoniske niveau.

Lad os prøve at lave en anmærkning.

For at gøre dette skal du oprette en fil, men i stedet for at skrive klasse eller interface , skriv @interface . Dette vil være filen for vores annotering. Den interne struktur af en annotering ligner den for en grænseflade.


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

@interface angiver, at dette er en annotering,
default siger, at parameteren vil have en specifik standardværdi.

Ta-da! Vi har lavet en annotation! Teoretisk kan vi allerede bruge det, men først ville det være bedre at konfigurere det.

Uden konfiguration kan vores annotering anvendes på hvad som helst (til klasser, metoder, attributter osv.), så det giver ikke meget mening at bruge det på dette tidspunkt. Hvor mærkeligt det end kan virke, skal vores annotering annoteres med andre annoteringer!

Lad os starte med @Target .

@ Target- annotationen (relevant siden Java 1.5) begrænser muligheden for at anvende en annotering. For at begrænse brugen til et bestemt niveau, skal vi sende et argument til @Target- annotationen for at angive, hvilke typer det kan anvendes på. Her er nogle af de almindeligt anvendte typer:

@Target(ElementType.PACKAGE) for pakker
@Target(ElementType.TYPE) for klasser
@Target(ElementType.CONSTRUCTOR) for konstruktører
@Target(ElementType.METHOD) for metoder
@Target(ElementType.FIELD) for attributter (variabler) i en klasse
@Target(ElementType.PARAMATER) for metodeparametre
@Target(ElementType.LOCAL_VARIABLE) for lokale variabler

Hvis du har brug for en annotering for flere typer, så kan du sende flere argumenter som en matrix:


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

Den næste vigtige del af konfigurationen er @Retention- annotationen.

Denne annotation angiver de dele af kodens livscyklus, hvor vores annotation vil være tilgængelig:

RetentionPolicy.SOURCE Annoteringer markeret med SOURCE- opbevaringspolitikken kasseres under kørsel.
RetentionPolicy.CLASS Anmærkninger markeret med CLASS- opbevaringspolitikken skrives til .class- filen, men fjernes ved kørsel.
RetentionPolicy.RUNTIME Annoteringer, der er markeret med RUNTIME- retentionspolitikken, fortsætter under kørsel og kan tilgås i vores program under kørsel.

Der er et par flere annotationer, du kan bruge til konfiguration:

Anmærkning Værdi
@Arvet Angiver, at en afledt klasse arver en overordnet klasses implementering af annoteringen.
@Dokumenteret Dette indikerer, at annotationen vil blive inkluderet i den genererede Javadoc-dokumentation.

Lad os nu prøve at skabe vores egen annotering.

Vi opretter en annotation, der er til klasser og metoder og indeholder oplysninger om kodens forfatter og version:


    @Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Info {
   String author() default "Author";
   String version() default "0.0";
}

Vi kan anvende vores anmærkning på metoder og klasser. Vores annotations metadata vil være tilgængelige på kørselstidspunktet. Vær opmærksom på vores annotations parametre: Vi kan levere to argumenter (forfatter og version), eller vi kan udelade dem. Hvis vi udelader dem, vil de angivne standardværdier ( standard "Author" og standard "0.0" ) blive brugt.

Det er værd at bemærke, at vi ikke behøver at angive en standardværdi for parametre. I dette tilfælde bliver parameteren obligatorisk.

Når vi sender argumenter, skal vi angive den tilsvarende parameter ved hjælp af notationsværdien = "værdi" . Parameteren skal altid navngives eksplicit, selvom annotationen har en enkelt parameter.

Lad os anvende vores anmærkning på et par klasser:


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