O principal benefício das anotações não vem de usar as padrão que já estão no JDK. Ao mesmo tempo, raramente há necessidade de criar sua própria anotação. Mas se estivermos desenvolvendo um sistema grande ou criando uma biblioteca separada, então, no nível da arquitetura, implementar nossa própria anotação certamente renderá dividendos.

Vamos tentar criar uma anotação.

Para fazer isso, crie um arquivo, mas em vez de escrever class ou interface , escreva @interface . Este será o arquivo para nossa anotação. A estrutura interna de uma anotação é semelhante à de uma interface.


public @interface Sum {
   int sum() default 0;
}

@interface indica que esta é uma anotação,
padrão diz que o parâmetro terá um valor padrão específico.

Ta-da! Criamos uma anotação! Teoricamente já podemos usá-lo, mas primeiro seria melhor configurá-lo.

Sem configuração, nossa anotação pode ser aplicada a qualquer coisa (a classes, métodos, atributos, etc.), então faz pouco sentido usá-la neste momento. Por mais estranho que pareça, nossa anotação precisa ser anotada com outras anotações!

Vamos começar com @Target .

A anotação @Target (relevante desde o Java 1.5) restringe a capacidade de aplicar uma anotação. Para limitar o uso a um determinado nível, precisamos passar um argumento para a anotação @Target para indicar a quais tipos ele pode ser aplicado. Aqui estão alguns dos tipos comumente usados:

@Target(ElementType.PACKAGE) para pacotes
@Target(ElementType.TYPE) para aulas
@Target(ElementType.CONSTRUCTOR) para construtores
@Target(ElementType.METHOD) para métodos
@Target(ElementType.FIELD) para atributos (variáveis) em uma classe
@Target(ElementType.PARAMATER) para parâmetros de método
@Target(ElementType.LOCAL_VARIABLE) para variáveis ​​locais

Se você precisar de uma anotação para vários tipos, poderá passar vários argumentos como uma matriz:


@Target({ ElementType.PARAMETER, ElementType.LOCAL_VARIABLE })

A próxima parte importante da configuração é a anotação @Retention .

Esta anotação indica as partes do ciclo de vida do código em que nossa anotação estará disponível:

RetentionPolicy.SOURCE As anotações marcadas com a política de retenção SOURCE são descartadas no tempo de execução.
RetentionPolicy.CLASS As anotações marcadas com a política de retenção CLASS são gravadas no arquivo .class , mas são removidas no tempo de execução.
Política de Retenção.RUNTIME As anotações marcadas com a política de retenção RUNTIME persistem em tempo de execução e podem ser acessadas em nosso programa em tempo de execução.

Existem mais algumas anotações que você pode usar para configuração:

Anotação Valor
@Inherited Indica que uma classe derivada herda a implementação da anotação de uma classe pai.
@Documentado Isso indica que a anotação será incluída na documentação Javadoc gerada.

Agora vamos tentar criar nossa própria anotação.

Vamos criar 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";
}

Podemos aplicar nossa anotação a métodos e classes. Os metadados de nossa anotação estarão disponíveis em tempo de execução. Preste atenção aos parâmetros da nossa anotação: Podemos fornecer dois argumentos (autor e versão), ou podemos omiti-los. Se os omitirmos, os valores padrão especificados ( padrão "Autor" e padrão "0,0" ) serão usados.

Vale a pena notar que não precisamos especificar um valor padrão para os parâmetros. Neste caso, o parâmetro torna-se obrigatório.

Ao passar argumentos, devemos especificar o parâmetro correspondente usando a notação value = "value" . O parâmetro sempre deve ser nomeado explicitamente, mesmo que a anotação tenha um único parâmetro.

Vamos aplicar nossa anotação a algumas classes:


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