W tym artykule dowiemy się jak używać adnotacji @Target przy tworzeniu własnej adnotacji.
@Target określa, w których miejscach konstruowana przez nas adnotacja może zostać użyta. Gdy zadeklarujemy, w jakich miejscach kodu jest możliwe użycie adnotacji, błędne jej umiejscowienie nie pozwoli na skompilowanie kodu.
Adnotacje tworzy się używając deklaracji interface ze znakiem @ na początku. Taka adnotacja nic nie robi, lecz program nie wyrzuci błędu przy kompilacji.
public @interface MyAnnotation {
}
Powyższa adnotacja nie ma zdefiniowanego miejsca, w którym możemy jej użyć. Aby to zrobić, należy dodać adnotację @Target, wraz z parametrami.
Parametry do adnotacji @Target możemy przekazać na 4 różne sposoby. W trzecim i czwartym przykładzie możliwe jest zdefiniowanie jednej lub większej liczby typów:
@Target(ElementType.FIELD)
@Target(value=ElementType.FIELD)
@Target({ElementType.FIELD, ElementType.CONSTRUCTOR})
@Target(value={ElementType.FIELD, ElementType.CONSTRUCTOR})
ElementType.ANNOTATION_TYPE - adnotacja do tworzenia adnotacji 🙂. Na przykład wymienione w tytule @Target() jest taką adnotacją. Inny przykład to @Retention() opisujące cykl życia adnotacji. Obie są oznaczone adnotacją ElementType.ANNOTATION_TYPE.@Target({ ElementType.ANNOTATION_TYPE })
public @interface MyAnnotation {
}
@MyAnnotation
@interface NewAnnotation {
}
ElementType.CONSTRUCTOR - przy deklaracji konstruktora.@Target({ ElementType.CONSTRUCTOR })
public @interface MyAnnotation {
}
public class NewClass {
@MyAnnotation
public NewClass(){}
}
ElementType.FIELD - przy deklaracji pola w klasie.@Target({ ElementType.FIELD })
public @interface MyAnnotation {
}
public class NewClass {
@MyAnnotation
private String text;
}
ElementType.LOCAL_VARIABLE - przy deklaracji lokalnej zmiennej (np. w funkcji). Nie mylić z deklaracją FIELD.@Target({ ElementType.LOCAL_VARIABLE })
public @interface MyAnnotation {
}
public class NewClass {
public void newFunction(){
@MyAnnotation
String text = "text";
}
}
ElementType.METHOD - przy deklaracji metody/funkcji.
@Target({ ElementType.METHOD })
public @interface MyAnnotation {
}
public class NewClass {
@MyAnnotation
public void newFunction(){}
}
ElementType.PACKAGE - przy deklaracji pakietu. Możliwe jedynie do dodania w pliku package-info.java!@Target({ ElementType.PACKAGE })
public @interface MyAnnotation {
}
@MyAnnotation
package mypackage; // tylko w pliku package-info.java
ElementType.PARAMETER - przy deklaracji parametrów metody/funkcji.@Target({ ElementType.PARAMETER })
public @interface MyAnnotation {
}
public class NewClass {
public void newFunction(@MyAnnotation int a, @MyAnnotation String b){}
}
ElementType.TYPE - przy deklaracji klasy, interfejsu, enuma.@Target({ ElementType.TYPE })
public @interface MyAnnotation {
}
@MyAnnotation
public class NewClass {
}
ElementType.TYPE_USE - od Javy 8. Wszędzie tam gdzie użyty jest typ. “As of the Java SE 8 release, annotations can also be applied to any type use. This means that annotations can be used anywhere you use a type. A few examples of where types are used are class instance creation expressions (new), casts, implements clauses, and throws clauses”.@Target({ ElementType.TYPE_USE })
public @interface MyAnnotation {
}
public class NewClass extends @MyAnnotation Object{
List< @MojaAdnotacja String> myList;
int a = (@MyAnnotation int) 4.21;
Exception e = new @MyAnnotation Exception();
}
ElementType.TYPE_PARAMETER- od Javy 8. Przy definiowaniu typów generycznych.@Target({ ElementType.TYPE_PARAMETER })
public @interface MyAnnotation {
}
public class NewClass< @MyAnnotation T>{
<@MyAnnotation U> void myMethod(){
}
}
W przypadku gdy nie zadeklarujemy, w którym miejscu możemy użyć adnotacji, możemy jej użyć wszędzie oprócz TYPE_USE i TYPE_PARAMETER.
public @interface MyAnnotation {
}
@MyAnnotation
@interface NewAnnotation {
}
@MyAnnotation
public class NewClass {
@MyAnnotation
String newField;
@MyAnnotation
public NewClass(){
}
@MyAnnotation
public void newFunction(@MyAnnotation String parametr){
@MyAnnotation String myLocalVariable;
}
}
Źródła: