Anotaciones y Decoradores en Java

Las anotaciones o decoradores sobre el código se han vuelto muy comunes en los últimos tiempos. Permiten al programador añadir información útil extra ya sea para comentar mejor el código o para modificar la forma de compilar/ejecutar una clase concreta. Son una extensión a Java para permitir la programación orientada a aspectos.

Las anotaciones pueden ser de tres tipos, según el momento en el que son visibles:

Información para el Compilador

Estas anotaciones permiten al compilador indicar si debe o no omitir errores y warnings o qué hacer con ellos. A nada que se haya trabajado con un IDE Java (como eclipse) se habrán utilizado este tipo de anotaciones de forma natural, por ejemplo usando @Override sobre una función para indicar que está sobreescribiendo una declaración definida en una clase padre. Esta anotación es completamente opcional,  pero permite tanto al compilador como al desarrollador comprobar que efectivamente se está sobreescribiendo una funcionalidad existente por herencia.

Por ejemplo:

public class Parent {     
    public void do(){
        System.out.println("Parent");
     }
}

public class Son extends Parent{     
    usando @Override
    public void do(){
        System.out.println("Son");
     }
}
Anotaciones en Tiempo de Compilación y Despliegue

Estas anotaciones permiten añadir información extra al compilador para que modifique la forma en la que se genera el código de los ficheros .class. Puede servir para modificar clases (añadiendo o modificando funcionalidad respecto a lo descrito en el código fuente), generar clases nuevas (por ejemplo en base a un fichero descriptor), etc...

Estas anotaciones sólo serán visibles en este punto, es decir, no se escribirán sobre los .class y por tanto no se podrán consultar en tiempo de ejecución.

Anotaciones en Tiempo de Ejecución

Estas anotaciones pueden ser consultadas en tiempo de ejecución y funcionan de forma muy parecida a como se utilizaría una interfaz.

Veamos directamente un ejemplo de cómo crear una anotación Runtime y cómo se puede utilizar. La anotación MyAnnotation se podrá aplicar a elementos de tipo field, es decir, a atributos de una clase:

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
     public @interface MyAnnotation {
}

Ahora podemos crear una clase que esté anotada con esta anotación:

public class myObject
 {
 @MyAnnotation
 public String field;
 }

De esta forma, en cualquier otra parte del código, podemos comprobar mediante reflexión si un objeto tiene un campo marcado con la anotación:

Class res = objeto.getClass();
for (Field f : res.getFields()) {
     if (f.isAnnotationPresent(MyAnnotation.class)) {
          System.out.println("OK");
      }
}

Más información: