A criação de anotações é um processo bastante simples, embora seja limitado por algumas regras. Agora precisamos descobrir a que propósito prático eles servem.

Vamos relembrar como criamos nossa própria anotação.

Escreveremos uma anotação que é para classes e métodos e contém informações sobre o autor e a versão do código:


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

Aqui estão nossas classes que anotamos:


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

Como podemos usar esses dados em tempo de execução?

Usando reflexão para extrair metadados de anotações. Lembre-se do que é reflexão. A reflexão é um mecanismo para examinar dados sobre um programa em tempo de execução. A reflexão permite obter informações sobre campos, métodos, construtores de classe e classes.

Usaremos a reflexão para ler as anotações em uma classe e exibir as informações que desejamos.

Leremos os dados de nossas classes no método main :


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();
       }
   }
}

Passamos uma instância de nossa classe para o método readMyClass .

Então podemos passar uma classe, bem como um método para o método readAnnotation . Vamos fazer isso — passaremos um objeto Class e um objeto Method. É necessário um objeto que implemente a interface AnnotatedElement . Isso nos permite obter uma lista de anotações do objeto e obter informações sobre cada uma delas.

Observe que só obtemos informações depois de verificar se a anotação pertence ao nosso tipo de anotação: if (annotation instanceof Info) .

A saída do programa nos dá informações completas das anotações:

Classe: annotation.MyClass1
Pesquisar anotações em java.lang.Class
Autor: Autor
Versão: 0.0
Pesquisar anotações em java.lang.reflect.Method
Autor: Autor
Versão: 0.0

Classe: annotation.MyClass2
Pesquisar anotações em java.lang.
Autor da classe : Autor
Versão: 2.0
Pesquisar anotações em java.lang.reflect.Method
Autor: Anônimo
Versão: 0.0

Classe: annotation.MyClass3
Pesquisar anotações em java.lang.Class
Autor: Anônimo
Versão: 2.0
Pesquisar anotações em java. lang.reflect.Method
Autor: Anônimo
Versão: 4.0

Assim, com a ajuda da reflexão, conseguimos extrair os metadados.

Agora vamos ver um exemplo de uso de anotações para melhorar o código, incluindo o aumento da legibilidade, velocidade e qualidade em geral. Lombok nos ajudará com isso.

Lombok é um plug-in de compilador que usa anotações para ocultar uma grande quantidade de código e estender a linguagem, simplificando o desenvolvimento e adicionando algumas funcionalidades.

Considere um exemplo de anotações do Lombok:

@Para sequenciar Gera uma implementação do método toString() que consiste em uma representação completa do objeto: o nome da classe, todos os campos e seus valores.

@ToString
public class Example
@EqualsAndHashCode Gera implementações de equals e hashCode que usam campos não estáticos e não estáticos por padrão, mas são configuráveis. Mais detalhes podem ser encontrados no site do projeto . Lá você encontrará um exemplo que usa @EqualsAndHashCode e também mostra uma implementação padrão sem a anotação.
@Getter / @Setter Gera getters e setters para campos privados.

@Getter 
@Setter 
private String name = "name";
@NonNull Usado para afirmar que os campos não são nulos quando um objeto é instanciado. Caso contrário, um NullPointerException é lançado.

public Example(@NonNull P p) {
 super("Hello");
 this.name = p.getName();
}

O Lombok tem muitas anotações mais úteis que são usadas com menos frequência. Consideramos suas anotações mais simples. Você pode ler mais sobre o projeto no site oficial .