Създаването на анотации е доста прост процес, въпреки че е ограничен от някои правила. Сега трябва да разберем 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) .

Резултатът от програмата ни дава пълна информация от анотациите:

Клас: annotation.MyClass1
Търсене на анотации в 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() , който се състои от цялостно представяне на обекта: името на класа, всички полета и техните стойности.
@ToString
public class Example
@EqualsAndHashCode Генерира реализации на equals и hashCode , които използват нестатични и нестатични полета по подразбиране, но могат да се конфигурират. Повече подробности можете да намерите на сайта на проекта . Там ще намерите пример, който използва @EqualsAndHashCode и също така показва стандартна реализация без анотацията.
@Getter / @Setter Генерира гетери и сетери за частни полета.
@Getter
@Setter
private String name = "name";
@NonNull Използва се, за да потвърди, че полетата не са нулеви, когато даден обект е инстанциран. В противен случай се хвърля изключение NullPointerException .
public Example(@NonNull P p) {
 super("Hello");
 this.name = p.getName();
}

Ломбок има много повече полезни анотации, които се използват по-рядко. Разгледахме най-простите му анотации. Повече за проекта можете да прочетете на официалния сайт .