Główną zaletą mechanizmu adnotacji nie jest korzystanie z gotowych standardowych adnotacji w JDK. Ale potrzeba stworzenia własnej adnotacji pojawia się rzadko. Na przykład, jeśli rozwijamy duży system lub izolujemy oddzielną bibliotekę, to na poziomie architektonicznym wdrożenie własnej adnotacji na pewno przyniesie efekty.

Spróbujmy utworzyć adnotację.

W tym celu tworzymy plik i zamiast klasy lub interfejsu piszemy @interface . To będzie nasz plik adnotacji. Wewnętrzna struktura adnotacji jest podobna do struktury interfejsu.

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

@interface wskazuje, że jest to adnotacja,
default wskazuje, że parametr default zwróci określoną wartość.

Stworzyliśmy adnotację i teoretycznie możemy już z niej korzystać, ale najpierw lepiej ją skonfigurować.

Faktem jest, że bez konfiguracji naszą adnotację można zastosować do wszystkiego (do klas, metod, atrybutów itp.), dlatego nie ma większego sensu jej używać. Bez względu na to, jak dziwnie to wygląda, nasza adnotacja musi być opatrzona innymi adnotacjami!

Zacznijmy od @Target .

Adnotacja @Target (istotna od wersji Java 1.5) ogranicza możliwość zastosowania konfigurowalnej adnotacji. Aby ograniczyć do pewnego poziomu, musimy przekazać parametr do adnotacji @Target wskazujący, dla jakich gatunków można go zastosować. Oto niektóre z powszechnie używanych typów:

@Target(TypElementu.PAKIET) dla paczek
@Target(TypElementu.TYP) na zajęcia
@Target(TypElementu. KONSTRUKTOR) dla konstruktorów
@Target(TypElementu.METODA) dla metod
@Target(TypElementu.POLE) dla atrybutów klas (zmiennych)
@Target(TypElementu.PARAMETR) dla parametrów metody
@Target(Typ elementu.LOCAL_VARIABLE) dla zmiennych lokalnych

Jeśli potrzebujesz adnotacji z kilkoma typami, możesz przekazać kilka parametrów jako tablicę:

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

Kolejnym ważnym elementem konfiguracyjnym jest adnotacja @Retention .

Ta adnotacja wskaże w jakim cyklu życia kodu będzie dostępna nasza adnotacja:

Zasady przechowywania.ŹRÓDŁO Adnotacje z adnotacją o zasadach przechowywania SOURCE są odrzucane w czasie wykonywania.
Zasady przechowywania.KLASA Adnotacje z adnotacjami dotyczącymi zasad przechowywania CLASS są zapisywane w pliku .class , ale usuwane w czasie wykonywania.
RetentionPolicy.RUNTIME Adnotacje z adnotacjami dotyczącymi zasad przechowywania RUNTIME są zachowywane w czasie wykonywania i można uzyskać do nich dostęp w naszym programie w czasie wykonywania.

Możesz także użyć kilku dodatkowych adnotacji do konfiguracji:

adnotacja Oznaczający
@Dziedziczny Umożliwia klasie pochodnej implementację dziedziczenia adnotacji klasy nadrzędnej.
@Udokumentowane Adnotacja zostanie umieszczona w wygenerowanej dokumentacji javadoc.

Spróbujmy teraz stworzyć własną adnotację.

Stwórzmy adnotację, która będzie adnotowała klasy i metody oraz zawierała informacje o autorze i wersji napisanego kodu:

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

Możemy zastosować naszą adnotację do metod i klas. Metadane naszej adnotacji będą dostępne na etapie wykonywania programu. Zwróć uwagę na parametry naszej adnotacji. Możemy zagnieździć dwa parametry: nazwę i wersję, ale nie możemy ich umieścić, a wtedy wartościami domyślnymi będą te, które określiliśmy ( domyślnie „Author” i domyślnie „0.0” ).

Warto zaznaczyć, że nie możemy podać domyślnej wartości parametrów. W takim przypadku parametr ten staje się obowiązkowy.

Podczas przekazywania parametrów obowiązkowe jest również określenie parametru, przez który przechodzimy value = "value" . Wyraźne wskazanie jest zawsze wymagane, nawet jeśli adnotacja ma jeden parametr.

Naszą adnotację stosujemy do kilku klas:

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