El principal beneficio de las anotaciones no proviene del uso de las estándar que ya están en el JDK. Al mismo tiempo, rara vez es necesario crear su propia anotación. Pero si estamos desarrollando un sistema grande o creando una biblioteca separada, entonces, a nivel arquitectónico, implementar nuestra propia anotación definitivamente generará dividendos.

Intentemos crear una anotación.

Para hacer esto, cree un archivo, pero en lugar de escribir clase o interfaz , escriba @interface . Este será el archivo para nuestra anotación. La estructura interna de una anotación es similar a la de una interfaz.


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

@interface indica que se trata de una anotación,
por defecto dice que el parámetro tendrá un valor predeterminado específico.

Ta-da! ¡Creamos una anotación! Teóricamente ya podemos usarlo, pero antes sería mejor configurarlo.

Sin configuración, nuestra anotación se puede aplicar a cualquier cosa (a clases, métodos, atributos, etc.), por lo que tiene poco sentido usarla en este punto. ¡Por extraño que parezca, nuestra anotación necesita ser anotada con otras anotaciones!

Comencemos con @Target .

La anotación @Target (relevante desde Java 1.5) restringe la capacidad de aplicar una anotación. Para limitar el uso a un cierto nivel, debemos pasar un argumento a la anotación @Target para indicar a qué tipos se puede aplicar. Estos son algunos de los tipos más utilizados:

@Target(TipoElemento.PAQUETE) para paquetes
@Target(TipoElemento.TIPO) para clases
@Target(TipoElemento.CONSTRUCTOR) para constructores
@Target(TipoElemento.MÉTODO) para métodos
@Target(TipoElemento.CAMPO) para atributos (variables) en una clase
@Target(TipoElemento.PARÁMETRO) para parámetros de método
@Target(TipoElemento.LOCAL_VARIABLE) para variables locales

Si necesita una anotación para varios tipos, puede pasar varios argumentos como una matriz:


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

La siguiente parte importante de la configuración es la anotación @Retention .

Esta anotación indica las partes del ciclo de vida del código en las que nuestra anotación estará disponible:

RetentionPolicy.SOURCE Las anotaciones marcadas con la política de retención SOURCE se descartan en tiempo de ejecución.
RetentionPolicy.CLASS Las anotaciones marcadas con la política de retención de CLASS se escriben en el archivo .class , pero se eliminan en tiempo de ejecución.
RetentionPolicy.RUNTIME Las anotaciones marcadas con la política de retención RUNTIME persisten en tiempo de ejecución y se puede acceder a ellas en nuestro programa en tiempo de ejecución.

Hay algunas anotaciones más que puede usar para la configuración:

Anotación Valor
@Inherited Indica que una clase derivada hereda la implementación de la anotación de una clase principal.
@Documented Esto indica que la anotación se incluirá en la documentación Javadoc generada.

Ahora intentemos crear nuestra propia anotación.

Crearemos una anotación que sea para clases y métodos y que contenga información sobre el autor y la versión del código:


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

Podemos aplicar nuestra anotación a métodos y clases. Los metadatos de nuestra anotación estarán disponibles en tiempo de ejecución. Preste atención a los parámetros de nuestra anotación: podemos proporcionar dos argumentos (autor y versión), o podemos omitirlos. Si los omitimos, se utilizarán los valores predeterminados especificados ( "Autor" predeterminado y "0.0" predeterminado ).

Vale la pena señalar que no tenemos que especificar un valor predeterminado para los parámetros. En este caso, el parámetro se vuelve obligatorio.

Al pasar argumentos, debemos especificar el parámetro correspondiente usando la notación value = "value" . El parámetro siempre debe tener un nombre explícito, incluso si la anotación tiene un solo parámetro.

Apliquemos nuestra anotación a algunas clases:


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