I'm working with Java 6's annotation processing, i.e. what can be found within javax.annotation.processing
(not Java 5's APT).
I wonder what the conceptional difference between the various Element
, Type
, and Mirror
classes is. As I don't really understand this, it's hard to efficiently program an annotation processor. There are various methods that 'convert' between these notions but I'm not really sure what I'm doing when using them.
So, for example, let me have an instance of AnnotationMirror
.
When I call getAnnotationType()
I get an instance of DeclaredType
(which implements TypeMirror
for whatever reason).
Then I can call asElement()
on this one and obtain an instance of Element
.
What has happened?
There is indeed on overlap between these concepts.
Element
models the static structure of the program, ie packages, classes, methods and variables. Just think of all you see in the package explorer of Eclipse.
Type
models the statically defined type constraints of the program, ie types, generic type parameters, generic type wildcards. Just think of everything that is part of Java's type declarations.
Mirror
is an alternative concept to reflection by Gilad Bracha and Dave Ungar initially developed for Self, a prototype-based Smalltalk dialect. The basic idea is to separate queries about the structure of code (and also runtime manipulation of the structure, alas not available in Java) from the domain objects. So to query an object about its methods, instead of calling #getClass
you would ask the system for a mirror through which you can see the reflection of the object. Thanks to that separation you can also mirror on classes that are not loaded (as is the case during annotation processing) or even classes in a remote image. For example V8 (Google's Javascript engine) uses mirrors for debugging Javascript code that runs in another object space.
The object of type javax.lang.model.element.AnnotationMirror
represents an annotation in your code.
The declared type represents the annotation class.
Its element is the generic class (see http://java.sun.com/javase/6/docs/api/javax/lang/model/element/TypeElement.html for more information on that matter). The element might be the generic version of a class, like List
, where as the declared type is the parametrized version, for instance List<String>
. However I'm not sure it is possible to have annotations classes use generics and thus the distinction might be irrelevant in that context.
For instance lets say you have the following JUnit4 method:
@Test(expected = MyException.class) public void myTest() { // do some tests on some class... }
The AnnotationMirror represents @Test(expected = NullPointerException.class)
. The declared type is the org.junit.Test
class. The element is more or less the same as there are no generics involved.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With