tutorial - notacion en java
RetentionPolicy CLASS vs. RUNTIME (3)
¿Cuál es la diferencia práctica entre RetentionPolicy.CLASS
y RetentionPolicy.RUNTIME
?
Parece que ambos están grabados en el bytecode y ambos se pueden acceder en el tiempo de ejecución de todos modos.
Anotaciones con política de retención
CLASS
yRUNTIME
son accesibles desde el código de clase byte. Necesitamos usar una biblioteca de manipulación de código de bytes (por ejemplo, ASM) para acceder a las Anotaciones disponibles en el código de bytes.
Ejemplo simple aquí - http://bethecoder.com/applications/tutorials/java/annotations/class-and-runtime-retention-policy.html
Parece que ambos están grabados en el bytecode y ambos se pueden acceder en el tiempo de ejecución de todos modos.
Falso para las interfaces de anotación integradas getAnnotations
como getAnnotations
. P.ej:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.CLASS)
@interface RetentionClass {}
@Retention(RetentionPolicy.RUNTIME)
@interface RetentionRuntime {}
public static void main(String[] args) {
@RetentionClass
class C {}
assert C.class.getAnnotations().length == 0;
@RetentionRuntime
class D {}
assert D.class.getAnnotations().length == 1;
}
por lo que la única forma de observar una anotación RetentionPolicy.CLASS
es mediante un analizador de códigos de bytes.
Otra diferencia es que la clase anotada Retention.CLASS
obtiene un RuntimeInvisible clase RuntimeInvisible , mientras que las anotaciones Retention.RUNTIME
obtienen un RuntimeVisible clase RuntimeVisible . Esto se puede observar con javap
.
Ejemplos en GitHub para que juegues.
ambos se pueden acceder en el tiempo de ejecución de todos modos.
Eso no es lo que dice el javadoc :
DURACIÓN: las anotaciones deben ser registradas en el archivo de clase por el compilador y retenidas por la VM en tiempo de ejecución, por lo que pueden leerse de manera reflexiva .
CLASE: las anotaciones deben ser registradas en el archivo de clase por el compilador, pero no es necesario que la VM las retenga en tiempo de ejecución .
En la práctica, no conozco ningún caso de uso para CLASS
. Solo sería útil si quisiera leer el bytecode programáticamente, en lugar de hacerlo a través de la API del cargador de clases, pero ese es un caso muy especializado, y no sé por qué no usaría simplemente RUNTIME
.
Irónicamente, CLASS
es el comportamiento predeterminado.