2011-03-25 7 views
9

Tengo algunas preguntas sobre el trabajo de anotaciones en java.¿Cómo trata el compilador las anotaciones?

Si las anotaciones no se pueden convertir en bytecode, ¿a dónde va esta información? ¿A dónde van los metadatos? ¿Cómo Java Reflection utiliza esta información?

¿Cómo se relaciona el compilador con las anotaciones?

Cuando decimos,

@Override 
public void doSomething(){ 
} 

¿Qué hace un compilador Java hacer con él?

Sé que comprueba la firma del método para que el método sea un método perfectamente anulado, pero ¿cómo?

+0

Vea si esto ayuda http://pawanz.wordpress.com/2010/12/12/taming-java-annotations/ – ashishjmeshram

Respuesta

0

Este es simple. El compilador simplemente comprueba la superclase para el método con el mismo nombre y el mismo número de parámetros, su orden y tipos. Si el método tiene la anotación @Override y no se ha encontrado dicho método, se genera un error.

La pregunta más interesante es cómo el compilador trata con las anotaciones, lo que significa en tiempo de ejecución. Supongo que se agregan en código de bytes pero en alguna sección especial con metainformación. Entonces, en tiempo de ejecución, jvm tiene acceso a la meta sección. Como prueba, siempre puede llamar al getAnnotations() en cualquier objeto class.

4

@Override es una fuente tipo de anotación - se utiliza para comprobar si un determinado método sigue el contrato de un método overriden - por lo tanto no está disponible en tiempo de ejecución (y por lo tanto lógicamente no existe en el código de bytes compilado).

Sé que verifica la firma del método para que el método debe ser un método perfectamente reemplazado, pero ¿cómo

En el proceso de lectura de los archivos de origen y su conversión a código de bytes, por ejemplo, no usando la reflexión en absoluto. Consulte The Java Programming Language Compiler - javac para obtener información adicional del compilador.

-2

Las anotaciones compiladas (que en última instancia son datos constantes) viven el archivo de clase y se pueden acceder con los métodos apropiados getAnnotations() y amigos.

+0

Gracias por la respuesta. ¿Puede explicar qué es un "grupo constante" y cómo se usa en tiempo de ejecución? – Gunwant

+0

Este es un área en el archivo de clase donde se almacenan datos constantes. Es posible que desee leer una referencia de JVM. – Ingo

+0

Gracias por la información útil. – Gunwant

3

Las anotaciones por ejemplo @Override implementado como public @interface @Override {} tiene un RetentionPolicy, que puede permitir la anotación a ser almacenado en un archivo de clase (RetentionPolicy.CLASS, RetentionPolicy.RUNTIME) o ser desechados (RetentionPolicy.SOURCE).

El método @Override tiene una RetentionPolicy de RetentionPolicy.SOURCE y un objetivo de ElementType.METHOD (lo que significa que este método solo se puede anotar en las declaraciones de métodos solamente).

@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.SOURCE) 
public @interface Override { 
} 

PS Si desea leer las anotaciones reflexivamente, se tendrá que establecer el RetentionPolicy en RetentionPolicy.RUNTIME.

2

Al principio, había 2 tipos de anotaciones: accesible en tiempo de ejecución (2 tipos) y no accesible en tiempo de ejecución. El comportamiento de la anotación se realiza mediante una política de retención a través de la anotación de la declaración de anotación :-). Ejemplo:

@Retention(RetentionPolicy.RUNTIME) // effectively visible to JVM Runtime 
public @interface MethodInfo { 
    String author() default "unspecified"; 
    String lastModification() default "unspecified"; // Format: yyyy-mm-dd 
    ImplementationStatus implementationStatus(); 
} 

JVM de tiempo de ejecución anotaciones visibles se puede acceder a través de la reflexión durante la ejecución de código anotado (o cuando se carga por la JVM). Utiliza esas anotaciones como titulares de metadatos. Los metadatos pueden ser procesados ​​por otro código para hacer varias cosas, ej. para verificar el estado de implementación del método anotado antes de que se ejecute un método determinado.

¡Pero alguien debe escribir el código para usar la anotación matedata a través de la reflexión! El mejor ejemplo es un servidor de aplicaciones (AS) que carga clases bajo demanda desde archivos JAR colocados en algún directorio particular. AS puede contener código que comprueba cada clase cargada para métodos estáticos anotados por la anotación @Initialization y ejecuta esos métodos de inmediato. Este tipo de anotación está definido por AS y aquellos que crean JAR y clases para AS lo usan durante el desarrollo.

Las anotaciones que no están disponibles durante el tiempo de ejecución se utilizan y resuelven durante la compilación. @Override es un buen ejemplo. Las anotaciones solo de fuente personalizada pueden ser usadas por los complementos del compilador o si el código es compilado por otro código bajo demanda.

Cuestiones relacionadas