Създаването на анотации е доста прост процес, въпреки че е ограничен от някои правила. Сега трябва да разберем Howва практическа цел служат.
Нека си припомним How създаваме собствена анотация.
Ще напишем анотация, която е за класове и методи и съдържа информация за автора и versionта на codeа:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Info {
String author() default "Author";
String version() default "0.0";
}
Ето нашите класове, които коментирахме:
@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() {}
}
Как можем да използваме тези данни по време на изпълнение?
Чрез използване на отражение за извличане на метаданни от анотации. Спомнете си Howво е отражение. Отражението е механизъм за изследване на данни за програма по време на изпълнение. Reflection ви позволява да получавате информация за полета, методи, конструктори на класове и класове.
Ще използваме отражение, за да прочетем анотациите в клас и да покажем информацията, която искаме.
Ще четем данни от нашите класове в основния метод:
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
public class Main {
public static void main(String[] args) throws NoSuchMethodException {
readMyClass(MyClass1.class);
readMyClass(MyClass2.class);
readMyClass(MyClass3.class);
}
static void readMyClass(Class<?> myClassObj) throws NoSuchMethodException {
System.out.println("\nClass: " + myClassObj.getName());
readAnnotation(myClassObj);
Method method = myClassObj.getMethod("myClassMethod");
readAnnotation(method);
}
static void readAnnotation(AnnotatedElement element) {
try {
System.out.println("Search for annotations in " + element.getClass().getName());
Annotation[] annotations = element.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation instanceof Info) {
final Info fileInfo = (Info) annotation;
System.out.println("Author: " + fileInfo.author());
System.out.println("Version: " + fileInfo.version());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Предаваме екземпляр от нашия клас на метода readMyClass .
След това можем да предадем клас, Howто и метод към метода readAnnotation . Нека направим това - ще предадем обект Class и обект Method. Необходим е обект, който имплементира интерфейса AnnotatedElement . Това ни позволява да получим списък с анотации от обекта и да получим информация за всеки от тях.
Имайте предвид, че получаваме информация само след като проверим дали анотацията принадлежи към нашия тип анотация: if (анотация instanceof Info) .
Резултатът от програмата ни дава пълна информация от анотациите:
Търсене на анотации в java.lang.Class
Author: Author
Версия: 0.0
Търсене на анотации в java.lang.reflect.Method
Author: Author
Версия: 0.0
Клас: annotation.MyClass2
Търсене на анотации в java.lang.
Author на класа : Author
Версия: 2.0
Търсене на анотации в java.lang.reflect.Method
Author: Анонимен
Версия: 0.0
Клас: annotation.MyClass3
Търсене на анотации в java.lang.Author на класа
: Анонимен
Версия: 2.0
Търсене на анотации в java. lang.reflect.Method
Author: Анонимен
Версия: 4.0
Така с помощта на отражение успяхме да извлечем метаданните.
Сега нека да разгледаме пример за използване на анотации за подобряване на codeа, включително увеличаване на четливостта, скоростта и качеството като цяло. Ломбок ще ни помогне с това.
Lombok е плъгин за компилатор, който използва анотации, за да скрие огромно количество code и да разшири езика, като по този начин опростява разработката и добавя някои функционалности.
Помислете за пример за анотации от Ломбок:
@ToString | Генерира имплементация на метода toString() , който се състои от цялостно представяне на обекта: името на класа, всички полета и техните стойности. |
|
@EqualsAndHashCode | Генерира реализации на equals и hashCode , които използват нестатични и нестатични полета по подразбиране, но могат да се конфигурират. | Повече подробности можете да намерите на сайта на проекта . Там ще намерите пример, който използва @EqualsAndHashCode и също така показва стандартна реализация без анотацията. |
@Getter / @Setter | Генерира гетери и сетери за частни полета. |
|
@NonNull | Използва се, за да потвърди, че полетата не са нулеви, когато даден обект е инстанциран. В противен случай се хвърля изключение NullPointerException . |
|
Ломбок има много повече полезни анотации, които се използват по-рядко. Разгледахме най-простите му анотации. Повече за проекта можете да прочетете на официалния сайт .
GO TO FULL VERSION