Den største fordelen med merknader kommer ikke fra å bruke standardene som allerede er i JDK. Samtidig er det sjelden behov for å lage din egen merknad. Men hvis vi utvikler et stort system eller oppretter et eget bibliotek, vil implementering av vår egen merknad definitivt gi utbytte på arkitektonisk nivå.

La oss prøve å lage en merknad.

For å gjøre dette, lag en fil, men i stedet for å skrive klasse eller grensesnitt , skriv @grensesnitt . Dette vil være filen for kommentaren vår. Den interne strukturen til en merknad ligner på den til et grensesnitt.


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

@grensesnitt indikerer at dette er en merknad,
default sier at parameteren vil ha en spesifikk standardverdi.

Ta-da! Vi har laget en kommentar! Teoretisk sett kan vi bruke det allerede, men først ville det være bedre å konfigurere det.

Uten konfigurasjon kan merknaden vår brukes på hva som helst (på klasser, metoder, attributter, etc.), så det gir liten mening å bruke den på dette tidspunktet. Hvor rart det kan virke, må merknaden vår merkes med andre merknader!

La oss starte med @Target .

@Target- kommentaren (relevant siden Java 1.5) begrenser muligheten til å bruke en merknad. For å begrense bruken til et visst nivå, må vi sende et argument til @Target- kommentaren for å indikere hvilke typer det kan brukes på. Her er noen av de vanligste typene:

@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 metodeparametere
@Target(ElementType.LOCAL_VARIABLE) for lokale variabler

Hvis du trenger en merknad for flere typer, kan du sende flere argumenter som en matrise:


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

Den neste viktige delen av konfigurasjonen er @Retention -kommentaren.

Denne merknaden angir delene av kodens livssyklus der merknaden vår vil være tilgjengelig:

RetentionPolicy.SOURCE Merknader merket med SOURCE- retningslinjene for oppbevaring forkastes under kjøring.
RetentionPolicy.CLASS Merknader merket med CLASS- oppbevaringspolicyen skrives til .class- filen, men fjernes under kjøring.
RetentionPolicy.RUNTIME Merknader merket med RUNTIME- retningslinjene for oppbevaring vedvarer under kjøring og kan nås i programmet vårt under kjøring.

Det er noen flere merknader du kan bruke for konfigurasjon:

Merknad Verdi
@Arvet Indikerer at en avledet klasse arver en overordnet klasses implementering av merknaden.
@Dokumentert Dette indikerer at merknaden vil bli inkludert i den genererte Javadoc-dokumentasjonen.

La oss nå prøve å lage vår egen merknad.

Vi lager en merknad som er for klasser og metoder og inneholder informasjon om kodens forfatter og versjon:


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

Vi kan bruke merknaden vår på metoder og klasser. Metadataene til kommentaren vår vil være tilgjengelig under kjøring. Vær oppmerksom på parameterne for kommentaren vår: Vi kan levere to argumenter (forfatter og versjon), eller vi kan utelate dem. Hvis vi utelater dem, vil de angitte standardverdiene ( standard "Author" og standard "0.0" ) brukes.

Det er verdt å merke seg at vi ikke trenger å spesifisere en standardverdi for parametere. I dette tilfellet blir parameteren obligatorisk.

Når vi sender argumenter, må vi spesifisere den tilsvarende parameteren ved å bruke notasjonsverdien = "verdi" . Parameteren må alltid navngis eksplisitt, selv om merknaden har en enkelt parameter.

La oss bruke kommentaren vår på noen få 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() {}
}