Java Annotations

As Anotações Java fornecem informações sobre o código. As anotações Java não têm efeito direto no código que elas anotam. No tutorial de anotações Java, vamos analisar o seguinte;

  1. Anotações Java integradas
  2. Como escrever Anotação Personalizada
  3. Uso de anotações e como analisá-las usando API de Reflexão.

Anotações Java

O Java 1.5 introduziu anotações e agora é amplamente utilizado em frameworks Java EE como o Hibernate, Jersey e Spring. A Anotação Java é metadados sobre o programa incorporados no próprio programa. Pode ser analisado pela ferramenta de análise de anotações ou pelo compilador. Também podemos especificar a disponibilidade da anotação apenas para o tempo de compilação ou até o tempo de execução. Antes das anotações Java, os metadados do programa estavam disponíveis por meio de comentários Java ou pelo Javadoc, mas a anotação oferece mais do que isso. Os metadados das anotações também podem estar disponíveis em tempo de execução e os analisadores de anotações podem usá-los para determinar o fluxo de processo. Por exemplo, no webservice Jersey adicionamos a anotação PATH com uma string URI a um método e, em tempo de execução, o Jersey a analisa para determinar o método a ser invocado para o padrão de URI fornecido.

Anotação Java Personalizada

Criar uma anotação personalizada é semelhante a escrever uma interface, exceto que a palavra-chave da interface é prefixada com o símbolo _@_. Podemos declarar métodos na anotação. Vamos ver um exemplo de anotação personalizada em Java e depois discutiremos suas características e pontos importantes.

package com.journaldev.annotations;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodInfo{
	String author() default "Pankaj";
	String date();
	int revision() default 1;
	String comments();
}

Alguns pontos importantes sobre anotações em Java são:

  1. Os métodos de anotação não podem ter parâmetros.
  2. Os tipos de retorno dos métodos de anotação estão limitados a primitivos, String, Enums, Annotation ou array desses tipos.
  3. Os métodos de anotação em Java podem ter valores padrão.
  4. As anotações podem ter meta-anotações anexadas a elas. Meta-anotações são usadas para fornecer informações sobre a anotação.

Meta-anotações em Java

Há cinco tipos de meta-anotações:

  1. @Documented – indica que os elementos que usam esta anotação devem ser documentados pelo javadoc e ferramentas similares. Este tipo deve ser usado para anotar as declarações de tipos cujas anotações afetam o uso dos elementos anotados por seus clientes. Se uma declaração de tipo for anotada com Documented, suas anotações tornam-se parte da API pública dos elementos anotados.
  2. @Alvo – indica os tipos de elemento de programa aos quais um tipo de anotação é aplicável. Alguns valores possíveis são TIPO, MÉTODO, CONSTRUTOR, CAMPO etc. Se a meta-anotação Alvo não estiver presente, então a anotação pode ser usada em qualquer elemento de programa.
  3. @Herdado – indica que um tipo de anotação é automaticamente herdado. Se o usuário consultar o tipo de anotação em uma declaração de classe e a declaração de classe não tiver nenhuma anotação para este tipo, então a superclasse da classe será automaticamente consultada para o tipo de anotação. Esse processo será repetido até que uma anotação para este tipo seja encontrada ou o topo da hierarquia de classes (Objeto) seja alcançado.
  4. @Retenção – indica por quanto tempo as anotações com o tipo anotado devem ser retidas. Ele recebe como argumento RetentionPolicy cujos valores possíveis são FONTE, CLASSE e EXECUÇÃO
  5. @Repetível – usado para indicar que o tipo de anotação cuja declaração ele anota é repetível.

Anotações embutidas em Java

Java fornece cinco anotações embutidas.

  1. @Override – Quando desejamos substituir um método da Superclasse, devemos usar esta anotação para informar ao compilador que estamos sobrescrevendo um método. Assim, quando o método da superclasse é removido ou alterado, o compilador mostrará uma mensagem de erro. Saiba por que sempre devemos usar java override annotation ao substituir um método.
  2. @Deprecated – Quando queremos que o compilador saiba que um método está obsoleto, devemos usar esta anotação. O Java recomenda que, no javadoc, forneçamos informações sobre por que esse método está obsoleto e qual é a alternativa a ser usada.
  3. @SuppressWarnings – Isso é apenas para informar ao compilador para ignorar avisos específicos que ele produz, por exemplo, ao usar tipos não processados em java generics. Sua política de retenção é SOURCE e é descartada pelo compilador.
  4. @FunctionalInterface – Esta anotação foi introduzida no Java 8 para indicar que a interface é destinada a ser uma interface funcional.
  5. @SafeVarargs – Uma afirmação do programador de que o corpo do método ou construtor anotado não realiza operações potencialmente inseguras em seu parâmetro varargs.

Exemplo de Anotações em Java

Vamos ver um exemplo em Java que mostra o uso de anotações embutidas em Java, assim como o uso de uma anotação personalizada criada por nós no exemplo acima.

package com.journaldev.annotations;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

public class AnnotationExample {

	public static void main(String[] args) {
	}

	@Override
	@MethodInfo(author = "Pankaj", comments = "Main method", date = "Nov 17 2012", revision = 1)
	public String toString() {
		return "Overriden toString method";
	}

	@Deprecated
	@MethodInfo(comments = "deprecated method", date = "Nov 17 2012")
	public static void oldMethod() {
		System.out.println("old method, don't use it.");
	}

	@SuppressWarnings({ "unchecked", "deprecation" })
	@MethodInfo(author = "Pankaj", comments = "Main method", date = "Nov 17 2012", revision = 10)
	public static void genericsTest() throws FileNotFoundException {
		List l = new ArrayList();
		l.add("abc");
		oldMethod();
	}

}

I believe above java annotation example is self-explanatory and showing the use of annotations in different cases.

Análise de Anotações em Java

Vamos usar Reflexão para analisar anotações em Java a partir de uma classe. Por favor, note que a Política de Retenção da Anotação deve ser RUNTIME, caso contrário, suas informações não estarão disponíveis em tempo de execução e não conseguiremos obter nenhum dado dela.

package com.journaldev.annotations;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class AnnotationParsing {

	public static void main(String[] args) {
		try {
			for (Method method : AnnotationParsing.class.getClassLoader()
					.loadClass(("com.journaldev.annotations.AnnotationExample")).getMethods()) {
				// verifica se a anotação MethodInfo está presente no método
				if (method.isAnnotationPresent(com.journaldev.annotations.MethodInfo.class)) {
					try {
						// itera todas as anotações disponíveis no método
						for (Annotation anno : method.getDeclaredAnnotations()) {
							System.out.println("Annotation in Method '" + method + "' : " + anno);
						}
						MethodInfo methodAnno = method.getAnnotation(MethodInfo.class);
						if (methodAnno.revision() == 1) {
							System.out.println("Method with revision no 1 = " + method);
						}

					} catch (Throwable ex) {
						ex.printStackTrace();
					}
				}
			}
		} catch (SecurityException | ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

}

O resultado do programa acima é:

Annotation in Method 'public java.lang.String com.journaldev.annotations.AnnotationExample.toString()' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=1, comments=Main method, date=Nov 17 2012)
Method with revision no 1 = public java.lang.String com.journaldev.annotations.AnnotationExample.toString()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.oldMethod()' : @java.lang.Deprecated()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.oldMethod()' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=1, comments=deprecated method, date=Nov 17 2012)
Method with revision no 1 = public static void com.journaldev.annotations.AnnotationExample.oldMethod()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.genericsTest() throws java.io.FileNotFoundException' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=10, comments=Main method, date=Nov 17 2012)

A API de Reflexão é muito poderosa e amplamente utilizada em Java, em frameworks J2EE como Spring, Hibernate, JUnit, confira Reflexão em Java. Isso é tudo para o tutorial de exemplo de anotações em Java, espero que você tenha aprendido algo com isso. Atualizações nas Anotações em Java:

  1. As especificações do Servlet 3.0 introduziram o uso de anotações para a configuração do Servlet e parâmetros de inicialização, leia mais em Tutorial Java Servlet.
  2. Podemos usar anotações no Struts 2 para configurar as classes de ação e páginas de resultado, verifique o exemplo funcional em Exemplo de Anotação Hello World do Struts 2.

Referência: Site da Oracle

Source:
https://www.digitalocean.com/community/tutorials/java-annotations