repeatable - java lang annotation tutorial
¿Cuál es la concepción detrás de: Tipo-Elemento-Espejo (3)
Estoy trabajando con el proceso de anotación de Java 6, es decir, qué se puede encontrar en javax.annotation.processing
(no en APT de Java 5).
Me pregunto cuál es la diferencia conceptual entre las diferentes clases de 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.
Entonces, por ejemplo, déjame tener una instancia de AnnotationMirror
.
Cuando llamo a getAnnotationType()
obtengo una instancia de DeclaredType
(que implementa TypeMirror
por cualquier razón).
Luego puedo llamar a asElement()
sobre este y obtener una instancia de Element
.
¿Lo que ha sucedido?
De hecho, existe una superposición entre estos conceptos.
Element
modela 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 desarrollado inicialmente 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 a#getClass
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.
El objeto de tipo javax.lang.model.element.AnnotationMirror
representa una anotación en tu 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 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.
Este documento puede ayudar a comprender el diseño del procesamiento de anotación Java 6:
Gilad Bracha y David Ungar. Espejos: Principios de diseño para las instalaciones de meta nivel de lenguajes de programación orientados a objetos. En Proc. del ACM Conf. en Programación orientada a objetos, sistemas, idiomas y aplicaciones, octubre de 2004.