Het belangrijkste voordeel van annotaties is niet het gebruik van de standaard annotaties die al in de JDK staan. Tegelijkertijd is het zelden nodig om uw eigen annotatie te maken. Maar als we een groot systeem ontwikkelen of een aparte bibliotheek creëren, dan zal het implementeren van onze eigen annotatie op architectonisch niveau zeker voordelen opleveren.

Laten we proberen een annotatie te maken.

Maak hiervoor een bestand aan, maar in plaats van class of interface te schrijven , schrijft u @interface . Dit wordt het bestand voor onze annotatie. De interne structuur van een annotatie is vergelijkbaar met die van een interface.

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

@interface geeft aan dat dit een annotatie is,
standaard zegt dat de parameter een specifieke standaardwaarde zal hebben.

Ta-da! We hebben een annotatie gemaakt! Theoretisch kunnen we het al gebruiken, maar het is beter om het eerst te configureren.

Zonder configuratie kan onze annotatie op alles worden toegepast (op klassen, methoden, attributen, enz.), dus het heeft op dit moment weinig zin om het te gebruiken. Hoe vreemd het ook mag lijken, onze annotatie moet worden geannoteerd met andere annotaties!

Laten we beginnen met @Target .

De @Target- annotatie (relevant sinds Java 1.5) beperkt de mogelijkheid om een ​​annotatie toe te passen. Om het gebruik tot een bepaald niveau te beperken, moeten we een argument doorgeven aan de @Target- annotatie om aan te geven op welke typen het kan worden toegepast. Hier zijn enkele veelgebruikte typen:

@Target(ElementType.PAKKET) voor pakketten
@Target(ElementType.TYPE) voor lessen
@Target(ElementType.CONSTRUCTOR) voor constructeurs
@Target(ElementType.METHODE) voor methoden
@Target(ElementType.VELD) voor attributen (variabelen) in een klasse
@Target(ElementType.PARAMATER) voor methodeparameters
@Target(ElementType.LOCAL_VARIABLE) voor lokale variabelen

Als u een annotatie voor verschillende typen nodig hebt, kunt u verschillende argumenten doorgeven als een array:

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

Het volgende belangrijke onderdeel van de configuratie is de @Retention- annotatie.

Deze annotatie geeft de delen van de codelevenscyclus aan waarin onze annotatie beschikbaar zal zijn:

Bewaarbeleid.BRON Annotaties gemarkeerd met het SOURCE- bewaarbeleid worden tijdens runtime verwijderd.
Bewaarbeleid.KLASSE Annotaties gemarkeerd met het CLASS- bewaarbeleid worden naar het .class- bestand geschreven, maar worden tijdens runtime verwijderd.
Retentiebeleid. RUNTIME Annotaties die zijn gemarkeerd met het RUNTIME- retentiebeleid blijven tijdens runtime bestaan ​​en zijn tijdens runtime toegankelijk in ons programma.

Er zijn nog een paar annotaties die u kunt gebruiken voor configuratie:

Annotatie Waarde
@Geërfd Geeft aan dat een afgeleide klasse de implementatie van de annotatie van een bovenliggende klasse overerft.
@Gedocumenteerd Dit geeft aan dat de annotatie wordt opgenomen in de gegenereerde Javadoc-documentatie.

Laten we nu proberen onze eigen annotatie te maken.

We maken een annotatie voor klassen en methoden en bevatten informatie over de auteur en versie van de code:

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

We kunnen onze annotatie toepassen op methoden en klassen. De metadata van onze annotatie zullen tijdens runtime beschikbaar zijn. Let op de parameters van onze annotatie: we kunnen twee argumenten opgeven (auteur en versie), of we kunnen ze weglaten. Als we ze weglaten, worden de opgegeven standaardwaarden ( standaard "Author" en standaard "0.0" ) gebruikt.

Het is vermeldenswaard dat we geen standaardwaarde voor parameters hoeven op te geven. In dit geval wordt de parameter verplicht.

Bij het doorgeven van argumenten moeten we de corresponderende parameter specificeren met behulp van de notatie value = "value" . De parameter moet altijd expliciet benoemd worden, zelfs als de annotatie een enkele parameter heeft.

Laten we onze annotatie toepassen op een paar klassen:

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