¿Alguien puede explicar de una manera clara las diferencias prácticas entre las java.lang.annotation.RetentionPolicyconstantes SOURCE, CLASSy RUNTIME?
Tampoco estoy exactamente seguro de lo que significa la frase "retener la anotación".
¿Alguien puede explicar de una manera clara las diferencias prácticas entre las java.lang.annotation.RetentionPolicyconstantes SOURCE, CLASSy RUNTIME?
Tampoco estoy exactamente seguro de lo que significa la frase "retener la anotación".
Respuestas:
RetentionPolicy.SOURCE: Descartar durante la compilación. Estas anotaciones no tienen ningún sentido después de que se haya completado la compilación, por lo que no están escritas en el código de bytes.
Ejemplo:@Override,@SuppressWarnings
RetentionPolicy.CLASS: Descartar durante la carga de clase. Útil cuando se realiza un procesamiento posterior a nivel de código de bytes. Sorprendentemente, este es el valor predeterminado.
RetentionPolicy.RUNTIME: No descartes. La anotación debe estar disponible para la reflexión en tiempo de ejecución. Ejemplo:@Deprecated
Fuente:
la antigua URL está muerta ahora
hunter_meta y reemplazada por hunter-meta-2-098036 . En caso de que incluso esto se caiga, estoy cargando la imagen de la página.
Imagen (haga clic con el botón derecho y seleccione 'Abrir imagen en nueva pestaña / ventana')

RetentionPolicy.CLASS
aptestá en desuso, consulte docs.oracle.com/javase/7/docs/technotes/guides/apt/… . Para descubrir anotaciones usando la reflexión, hay múltiples tutoriales en internet. Puede comenzar buscando java.lang.Class::getAnno*y métodos similares en java.lang.reflect.Methody java.lang.reflect.Field.
Según sus comentarios sobre la descompilación de clases, así es como creo que debería funcionar:
RetentionPolicy.SOURCE: No aparecerá en la clase descompilada
RetentionPolicy.CLASS: Aparece en la clase descompilada, pero no se puede inspeccionar en tiempo de ejecución con reflexión con getAnnotations()
RetentionPolicy.RUNTIME: Aparece en la clase descompilada y se puede inspeccionar en tiempo de ejecución con reflexión con getAnnotations()
Ejemplo ejecutable mínimo
Nivel de idioma :
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.SOURCE)
@interface RetentionSource {}
@Retention(RetentionPolicy.CLASS)
@interface RetentionClass {}
@Retention(RetentionPolicy.RUNTIME)
@interface RetentionRuntime {}
public static void main(String[] args) {
@RetentionSource
class B {}
assert B.class.getAnnotations().length == 0;
@RetentionClass
class C {}
assert C.class.getAnnotations().length == 0;
@RetentionRuntime
class D {}
assert D.class.getAnnotations().length == 1;
}
Nivel de código de bytes : mediante el uso javapobservamos que la Retention.CLASSclase anotada obtiene un atributo de clase RuntimeInvisible :
#14 = Utf8 LRetentionClass;
[...]
RuntimeInvisibleAnnotations:
0: #14()
mientras que la Retention.RUNTIMEanotación obtiene un atributo de clase RuntimeVisible :
#14 = Utf8 LRetentionRuntime;
[...]
RuntimeVisibleAnnotations:
0: #14()
y el Runtime.SOURCEanotado .classno recibe ninguna anotación.
Ejemplos en GitHub para que juegues.
Política de retención: una política de retención determina en qué momento se descarta una anotación. Se especifica utilizando las anotaciones incorporadas de Java: @Retention[Acerca de]
1.SOURCE: annotation retained only in the source file and is discarded
during compilation.
2.CLASS: annotation stored in the .class file during compilation,
not available in the run time.
3.RUNTIME: annotation stored in the .class file and available in the run time.