springlayout - swing fillers java
¿Cómo afectan las diferentes políticas de retención a mis anotaciones? (5)
¿Alguien puede explicar de forma clara las diferencias prácticas entre las constantes java.lang.annotation.RetentionPolicy
SOURCE
, CLASS
y RUNTIME
?
Tampoco estoy exactamente seguro de lo que significa la frase "retención de anotación".
RetentionPolicy.SOURCE
: descarte durante la compilación. Estas anotaciones no tienen ningún sentido una vez completada la compilación, por lo que no están escritas en el bytecode.
Ejemplo:@Override
,@SuppressWarnings
RetentionPolicy.CLASS
: descartar durante la carga de la clase. Útil cuando se realiza el postproceso a nivel de código de bytes. Sorprendentemente, este es el valor predeterminado.
RetentionPolicy.RUNTIME
: no descartar. La anotación debería estar disponible para la reflexión en tiempo de ejecución. Ejemplo:@Deprecated
Fuente: La antigua URL ahora está muerta 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.
Image (clic derecho y seleccionar ''Abrir imagen en una nueva pestaña / ventana'')
De acuerdo con sus comentarios sobre la descompilación de clases, aquí es cómo creo que debería funcionar:
RetentionPolicy.SOURCE
: no aparecerá en la clase descompiladaRetentionPolicy.CLASS
: aparece en la clase descompilada, pero no se puede inspeccionar en tiempo de ejecución con reflejo congetAnnotations()
RetentionPolicy.RUNTIME
: aparece en la clase descompilada, y se puede inspeccionar en tiempo de ejecución con reflexión congetAnnotations()
Política de retención: una política de retención determina en qué punto se descarta una anotación.
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.
Una política de retención se especifica utilizando las anotaciones incorporadas de Java: @Retention.
RetentionPolicy.SOURCE
: la anotación estaría disponible en el código fuente del programa, no estaría en el archivo .class ni estaría disponible en el tiempo de ejecución. Utilizado por el compilador.
RetentionPolicy.CLASS
: la anotación estaría en el archivo .class, pero no estaría disponible en tiempo de ejecución. Utilizado por herramientas de manipulación de código de bytes, como ASM, realiza las modificaciones
RetentionPolicy.RUNTIME
: la anotación estaría disponible en el archivo .class y en el tiempo de ejecución, para su inspección a través de la reflexión java a través de 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 bytecode : utilizando javap
observamos que la clase anotada Retention.CLASS
obtiene un RuntimeInvisible clase RuntimeInvisible :
#14 = Utf8 LRetentionClass;
[...]
RuntimeInvisibleAnnotations:
0: #14()
mientras que la anotación Retention.RUNTIME
obtiene un RuntimeVisible clase RuntimeVisible :
#14 = Utf8 LRetentionRuntime;
[...]
RuntimeVisibleAnnotations:
0: #14()
y el Runtime.SOURCE
.class
anotado de Runtime.SOURCE
no obtiene ninguna anotación.
Ejemplos en GitHub para que juegues.