2010-10-03 16 views
20

según API Java Anotación:Java Anotaciones - en busca de un ejemplo de RetentionPolicy.CLASS

  • RetentionPolicy.CLASS Las anotaciones se van a grabar en el archivo de clase por el compilador pero no tiene por qué ser retenido por la VM en tiempo de ejecución.

  • RetentionPolicy.RUNTIME Las anotaciones se van a grabar en el archivo de clase por el compilador y retenido por la máquina virtual durante la ejecución tiempo, de modo que pueda ser leído reflexivamente.

Busco a una muestra de la política de retención "clase". cuando necesitamos usar esta política en lugar de la política RUNTIME.

Respuesta

9

De todas las gran cantidad de bibliotecas que tengo en mi proyecto actual. los únicos ejemplos que puedo encontrar están en la biblioteca Google Guava, por ejemplo com.google.common.annotations.GwtCompatible.

No estoy seguro de por qué eligieron esta política de retención, quizás para el soporte de herramientas, donde las herramientas leen los archivos de clase, en lugar de pasar por la API de reflexión. Sin embargo, no estoy seguro de que realmente vea el objetivo de esta distinción.

15

CLASE Las anotaciones se utilizan en herramientas de ofuscador como http://proguard.sourceforge.net. Por ejemplo, la anotación @KeepName deshabilita el cambio de nombre de nombre cuando necesita que su nombre de clase no se modifique para poder llamar a métodos como Class.forName().

1

ejemplo Minimal

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; 
} 

Si utilizamos javap en las clases anotadas, vemos que el Retention.CLASS clase anotada consigue un atributo de clase RuntimeInvisible:

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

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

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

que la información esté presente en ambos casos en el código de bytes.

Por lo tanto, Runtime.CLASS se puede utilizar para asociar metadatos arbitrarios a una clase que las herramientas de manipulación de códigos de bytes pueden usar, sin interferir con el comportamiento de tiempo de ejecución visible.

Examples on GitHub para que juegue.

+0

Si descompilo una clase que tiene la anotación 'RetentionPolicy.CLASS' (por ejemplo,' @ VisibleForTesting' de Guava), entonces la anotación no se muestra en el archivo de clase descompilado. Pero según javadoc, este tipo de anotación se registra en el archivo de la clase, entonces, por qué no se muestra en el archivo java descompilado. ¿Alguna idea? – tuk