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.

We have three types of annotations based on the moment of usage:

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) probably you would have used this type of annotations. For example, you can use usando @Override on a function to indicate that you are overwriting a method defined on a parent class. 

This annotation is completely optional, but allows both the compiler and the developer to check that they are indeed overwriting existing hierarchical functionality.

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

These annotations allow the compiler to add extra information about how to generate the code. By adding or modifying functionality from that in the source code you can alter how a class behaves. Also to create new classes (based on a file descriptor), etc …

These annotations will only be visible at this point. They are not compiled to the .class files. Therefore they are not available at runtime.

Anotaciones en Tiempo de Ejecución

You can use this annotations on runtime and they work on a very similar way as an interface.

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: