2010-06-24 14 views
115

¿Alguien puede explicar de manera clara las diferencias prácticas entre las constantes java.lang.annotation.RetentionPolicySOURCE, CLASS y RUNTIME?¿Cómo afectan las diferentes políticas de retención a mis anotaciones?

Tampoco estoy exactamente seguro de lo que significa la frase "anotación de retención".

+4

La documentación (http://java.sun.com/j2se/1.5.0/docs/api/java/lang/annotation/RetentionPolicy.html) es muy clara. –

+0

sí, ya lo leí pero no entiendo en la práctica cómo funciona. De hecho, si intento 'esta frase': "" "" El compilador debe registrar las anotaciones en el archivo de clase, pero no es necesario que la VM las retenga en tiempo de ejecución."" " y luego abra una clase decompilada donde puse una anotación con la política de retención CLASE I no encuentro nada ... – xdevel2000

+2

Entonces su decompilador no parece ser compatible con las anotaciones. Jd-gui funciona bien. – musiKk

Respuesta

136
  • RetentionPolicy.SOURCE: Descartar durante la compilación. Estas anotaciones no tienen sentido una vez que la compilación tiene completado, por lo que no están escritas en bytecode.
    Ejemplo: @Override, @SuppressWarnings

  • RetentionPolicy.CLASS: Descartar durante carga clase. Útil al hacer post-procesamiento de nivel de código de bytes. Sorprendentemente, este es el predeterminado.

  • RetentionPolicy.RUNTIME: Do not descartar. La anotación debe ser disponible para la reflexión en tiempo de ejecución. Ejemplo: @Deprecated

Fuente: La dirección de edad ha muerto hunter_meta y reemplazado con 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') enter image description here

+1

gracias por la cita, lo más interesante aquí es el caso de uso para 'RetentionPolicy.CLASS' – Max

+1

¿Puedes explicar por qué RetentionPolicy.class es interesante/sorprendentemente el ¿predeterminado? – sudocoder

+1

@sudocoder - Consulte estos enlaces: http://stackoverflow.com/a/5971247/373861 y http://stackoverflow.com/a/3849602/373861. Creo que esta política en particular es necesaria para la instrumentación de bytecode. Aunque nunca lo usé yo mismo. – Favonius

34

De acuerdo con sus comentarios acerca de la descompilación de clase, así es como creo que debería funcionar:

  • RetentionPolicy.SOURCE: no aparecerán en la clase descompilada

  • RetentionPolicy.CLASS: aparecen en el descompilada clase, pero no pueden ser inspeccionados en tiempo de ejecución con la reflexión con getAnnotations()

  • RetentionPolicy.RUNTIME: Aparecen en la clase descompilación, y puede ser consultada en tiempo de ejecución con la reflexión con getAnnotations()

+0

Sí, así lo pensé, pero en la clase descompilada, ¡nada está presente! ! y por lo tanto estoy confundido ... Trataré de inspeccionar el archivo de clase con la herramienta javap – xdevel2000

+0

javap no devuelve nada ¿dónde están puestos entonces? – xdevel2000

+0

Corto y dulce, y exactamente lo que estaba buscando. – Matt

13

Mínimo ejemplo ejecutable

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 Bytecode: usando javap observamos que la clase anotada Retention.CLASS consigue un atributo RuntimeInvisible clase:

#14 = Utf8    LRetentionClass; 
[...] 
RuntimeInvisibleAnnotations: 
    0: #14() 

mientras Retention.RUNTIME anotación consigue un atributo RuntimeVisible clase:

#14 = Utf8    LRetentionRuntime; 
[...] 
RuntimeVisibleAnnotations: 
    0: #14() 

y la Runtime.SOURCE anotado .class no obtiene ninguna anotación.

Examples on GitHub para que juegues con.

7

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.

0

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 las herramientas de manipulación de código de bytes como ASM realizar las modificaciones
RetentionPolicy.RUNTIME: La anotación estaría disponible en .class file y runtime, para su inspección a través de java reflection a través de getAnnotations().

Cuestiones relacionadas