¿Alguien puede explicar de una manera clara las diferencias prácticas entre las java.lang.annotation.RetentionPolicy
constantes SOURCE
, CLASS
y 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.RetentionPolicy
constantes SOURCE
, CLASS
y 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
apt
está 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.Method
y 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 javap
observamos que la Retention.CLASS
clase anotada obtiene un atributo de clase RuntimeInvisible :
#14 = Utf8 LRetentionClass;
[...]
RuntimeInvisibleAnnotations:
0: #14()
mientras que la Retention.RUNTIME
anotación obtiene un atributo de clase RuntimeVisible :
#14 = Utf8 LRetentionRuntime;
[...]
RuntimeVisibleAnnotations:
0: #14()
y el Runtime.SOURCE
anotado .class
no 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.