2010-01-23 9 views
17

Estoy trabajando con el proceso de anotación de Java 6, es decir, lo que se puede encontrar en javax.annotation.processing (no APT de Java 5).¿Cuál es la concepción detrás: Tipo - Elemento - Espejo

Me pregunto cuál es la diferencia conceptual entre las diferentes clases Element, Type y Mirror. Como realmente no entiendo esto, es difícil programar eficientemente un procesador de anotación. Hay varios métodos que 'convertir' entre estas nociones, pero no estoy muy seguro de lo que estoy haciendo al usarlos.

Por lo tanto, permítame tener una instancia de AnnotationMirror.
Cuando llamo al getAnnotationType() obtengo una instancia de DeclaredType (que implementa TypeMirror por cualquier razón).
Luego puedo llamar al asElement() en este caso y obtener una instancia de Element.
¿Qué ha pasado?

Respuesta

5

El objeto de tipo javax.lang.model.element.AnnotationMirror representa una anotación en su código.

El tipo declarado representa la clase de anotación.

Su elemento es la clase genérica (consulte http://java.sun.com/javase/6/docs/api/javax/lang/model/element/TypeElement.html para obtener más información al respecto). El elemento podría ser la versión genérica de una clase, como List, donde como el tipo declarado es la versión parametrizada, por ejemplo List<String>. Sin embargo, no estoy seguro de que sea posible que las clases de anotaciones usen genéricos y, por lo tanto, la distinción puede ser irrelevante en ese contexto.

Por ejemplo digamos que usted tiene el siguiente método junit4:

@Test(expected = MyException.class) 
public void myTest() { 
    // do some tests on some class... 
} 

El AnnotationMirror representa @Test(expected = NullPointerException.class). El tipo declarado es la clase org.junit.Test. El elemento es más o menos el mismo ya que no hay genéricos involucrados.

+0

El javadoc no es realmente claro sobre qué es TypeElement. Creo que está más vinculado a la declaración del tipo (por lo tanto, los parámetros de tipo), mientras que TypeDeclaration (nombre confuso) está más vinculado al uso del tipo como, por ejemplo, en una declaración de variable. Me da la idea de que estos dos términos son difíciles de entender en el contexto de las anotaciones. – Wolfgang

+0

Pero según esta [pregunta] (http://stackoverflow.com/questions/31245638/understanding-typeelement-and-declaredtype-interface-in-java), 'DeclareType' debe ser' MyException.class' – overexchange

5

Este documento puede ayudar a entender el diseño de Java procesamiento 6 anotación:

Gilad Bracha y David Ungar. Mirrors: Design Principles for Meta-level Facilities of Object-Oriented Programming Languages. En el Proc. de el ACM Conf. en de programación, sistemas, lenguajes y aplicaciones, octubre de 2004.

+0

Por lo tanto, en su lugar de api de reflexión como 'getClass' en el sistema de reflexión tradicional, ¿tenemos api de refección basadas en espejo? 'java.lang.model.element.AnnotationMirror' es algo así como' ClassMirror' (como se menciona en este documento)? – overexchange

19

En efecto, existe en la superposición entre estos conceptos orientados a objetos.

  • Element modelos la estructura estática del programa, es decir, paquetes, clases, métodos y variables. Solo piense en todo lo que ve en el paquete explorador de Eclipse.

  • Type modela las restricciones de tipo definidas estáticamente del programa, es decir, tipos, parámetros de tipo genérico, comodines de tipo genérico. Solo piense en todo lo que forma parte de las declaraciones de tipos de Java.

  • Mirror es un concepto alternativo a la reflexión de Gilad Bracha y Dave Ungar inicialmente desarrollado para Self, un dialecto Smalltalk basado en prototipos.La idea básica es separar las consultas sobre la estructura del código (y también la manipulación del tiempo de ejecución de la estructura, por desgracia no disponible en Java) de los objetos del dominio. Por lo tanto, para consultar un objeto sobre sus métodos, en lugar de llamar al #getClass, le pediría al sistema un espejo a través del cual pueda ver el reflejo del objeto. Gracias a esa separación también puede reflejar en clases que no están cargadas (como es el caso durante el procesamiento de anotación) o incluso clases en una imagen remota. Por ejemplo, V8 (el motor de Javascript de Google) usa mirrors para depurar código JavaScript que se ejecuta en otro espacio de objetos.

+1

Comprender este punto "también puede reflejar en clases que no están cargadas (como es el caso durante el proceso de anotación) realmente me ayudó a trabajar con el procesador de anotación. – Guillaume

Cuestiones relacionadas