¿Qué es @Retention en Java y cómo afecta a las anotaciones?

| Última modificación: 11 de diciembre de 2024 | Tiempo de Lectura: 3 minutos

Algunos de nuestros reconocimientos:

Premios KeepCoding

Y las java annotations…¿cuánto tiempo deben estar disponibles en mi código? ¿También te lo has preguntado? Pues, por muy irónico que parezca, esto lo solucionarás con otra anotación llamada @Retention en Java. Sí, gracias a ella podrás definir si estarán solo en tiempo de compilación, de ejecución o de clase. Aquí te explico más.

@Retention en Java qué es

¿Qué es @Retention en Java?

@Retention en Java es una meta-anotación, por eso es que se usa para anotar otras anotaciones. Te ayudará a especificar cuánto tiempo estarán disponibles las anotaciones que vas a aplicar. Esto se controla mediante las llamadas políticas de retención (retention policies).

Por si no lo sabías, Java tiene tres tipos de políticas de retención:

  1. RetentionPolicy.SOURCE: Las anotaciones con esta política se descartan después de la compilación. Solo son visibles para el compilador.
  2. RetentionPolicy.CLASS: Estas anotaciones se incluyen en los archivos .class pero no están disponibles en tiempo de ejecución. Es la política predeterminada en Java.
  3. RetentionPolicy.RUNTIME: Las anotaciones con esta política permanecen accesibles en tiempo de ejecución y pueden ser procesadas usando reflection.

¿Por qué es importante la política de retención?

Piénsalo así: cada una de estas políticas te dice cómo y cuándo puedes acceder a una anotación. Entonces, si necesitas que tu anotación sea evaluada o procesada en tiempo de ejecución (por ejemplo, para frameworks como Spring o Hibernate), debes usar RetentionPolicy.RUNTIME.

Por otro lado, si solo necesitas información para el compilador (como verificar algo durante la construcción del código), RetentionPolicy.SOURCE será más que suficiente.

Ejemplo de RetentionPolicy.SOURCE

Imagina que vas a crear una anotación para generar documentación automática. Como solo necesitas esta anotación mientras compilas el código, usarás RetentionPolicy.SOURCE así:

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

@Retention(RetentionPolicy.SOURCE)
@interface Documentation {
String author();
String version();
}

@Documentation(author = "Ana", version = "1.0")
public class ExampleClass {
// Clase sin impacto en tiempo de ejecución
}

Cuando compiles, el compilador podrá leer la anotación para generar la documentación, pero en tiempo de ejecución, desaparecerá.

Ejemplo de RetentionPolicy.CLASS

Recuerda siempre que, las anotaciones con RetentionPolicy.CLASS permanecen en el archivo .class, pero no están disponibles en tiempo de ejecución.

Este es el comportamiento predeterminado en Java.

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

@Retention(RetentionPolicy.CLASS)
@interface Metadata {
String info();
}

@Metadata(info = "Clase de utilidad")
public class UtilityClass {
// Esta anotación estará en el archivo .class
}

¿Te diste cuenta? aunque la anotación @Metadata se incluye en el archivo .class, no podrás acceder a ella usando reflection.

Ejemplo de RetentionPolicy.RUNTIME

Ahora, si necesitas que una anotación sea accesible durante la ejecución del programa, debes usar RetentionPolicy.RUNTIME. La tendrás que usar en frameworks y herramientas que procesen anotaciones dinámicamente.

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

@Retention(RetentionPolicy.RUNTIME)
@interface Config {
String key();
String value();
}

@Config(key = "appName", value = "MyApplication")
public class ConfigManager {
public static void main(String[] args) {
// Usando reflection para acceder a la anotación
Config config = ConfigManager.class.getAnnotation(Config.class);
if (config != null) {
System.out.println("Key: " + config.key());
System.out.println("Value: " + config.value());
}
}
}

Salida del programa:

Key: appName
Value: MyApplication

Observa bien que sí se puede leer la anotación @Config en tiempo de ejecución para obtener información clave.

¿Cómo elegir la política de retención adecuada?

Al momento de elegir la política de retención adecuada muchos lidian y se tardan pensando cómo hacerlo. La verdad es que dependerá del propósito de tu anotación. Voy a explicarte el propósito de cada política y así tú decides:

  • SOURCE: Para anotaciones temporales, como comentarios o instrucciones al compilador.
  • CLASS: Para información que debe ser registrada en el archivo .class pero no necesita estar disponible en tiempo de ejecución.
  • RUNTIME: Para casos donde las anotaciones deben ser procesadas dinámicamente, como en el caso de frameworks o herramientas de inyección de dependencias.

Creo que ya te diste cuenta de que @Retention en Java es una súper herramienta con la que controlarás cómo y cuándo tus anotaciones son accesibles. Eso sí, asegúrate de entender muy bien las políticas de retención (vuelve a ver cada ejemplo) para que logres escribir código más limpio y eficiente, y que las anotaciones se usen en el contexto adecuado.

¿Quieres aprender más sobre anotaciones, reflexión y otras herramientas avanzadas en Java? En el Bootcamp de Java Full Stack de KeepCoding, te llevaremos de cero a experto en el desarrollo con Java. Descubre cómo escribir código profesional que no solo funcione, sino que transforme tu carrera en el sector IT. ¡Apúntate ahora y da el salto hacia el futuro de la programación!

Ramón Maldonado

Full Stack Developer y Responsable de Formación base en KeepCoding.

Posts más leídos

¡CONVOCATORIA ABIERTA!

Java y Spring Boot

Full Stack Bootcamp

Clases en Directo | Profesores en Activo | Temario 100% actualizado