views:

74

answers:

3

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?

+3  A: 

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.

Guillaume Alvarez
The javadoc is not really clear about what the TypeElement is. I think it is more tied to the declaration of the type (thus the type parameters) while the TypeDeclaration (confusing name) is more tied to the use of the type like, for example, in a variable declaration. I get the idea that these two terms are hard to understand in the context of annotations.
Wolfgang
+3  A: 

This paper may help understanding the design of Java 6 annotation processing:

Gilad Bracha and David Ungar. Mirrors: Design Principles for Meta-level Facilities of Object-Oriented Programming Languages. In Proc. of the ACM Conf. on Object-Oriented Programming, Systems, Languages and Applications, October 2004.

Yardena
+1  A: 

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.

Adrian