背后的概念是什么:类型 – 元素 – 镜子

我正在使用Java 6的注释处理,即可以在javax.annotation.processing (而不是Java 5的APT)中找到的内容。

我想知道各种ElementTypeMirror类之间的概念差异是什么。 由于我不太明白这一点,因此很难有效地编写注释处理器。 有各种方法可以在这些概念之间“转换”,但我不确定在使用它们时我在做什么。

所以,例如,让我有一个AnnotationMirror实例。
当我调用getAnnotationType()我得到一个DeclaredType实例(由于某种原因它实现了TypeMirror )。
然后我可以在这个上调用asElement()并获取Element的实例。
发生了什么事?

javax.lang.model.element.AnnotationMirror类型的对象表示代码中的注释。

声明的类型表示注释类。

它的元素是generics类(有关该问题的更多信息,请参阅http://java.sun.com/javase/6/docs/api/javax/lang/model/element/TypeElement.html )。 该元素可能是类的通用版本,如List ,其中声明的类型是参数化版本,例如List 。 但是我不确定注释类是否可以使用generics,因此在该上下文中区别可能是无关紧要的。

例如,假设您有以下JUnit4方法:

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

AnnotationMirror表示@Test(expected = NullPointerException.class) 。 声明的类型是org.junit.Test类。 元素或多或少与没有涉及generics的元素相同。

这些概念确实存在重叠。

  • Element模拟程序的静态结构,即包,类,方法和变量。 想想你在Eclipse的包浏览器中看到的所有内容。

  • Type模型程序的静态定义类型约束,即类型,generics类型参数,generics类型通配符。 想一想Java类型声明中的所有内容。

  • Mirror是Gilad Bracha和Dave Ungar最初为Self开发的一种替代概念,Self是一种基于原型的Smalltalk方言。 基本思想是从域对象中分离有关代码结构的查询(以及结构的运行时操作,以及Java中不可用)。 因此,要查询对象的方法,而不是调用#getClass您可以向系统询问镜像,通过该镜像可以看到对象的reflection。 由于这种分离,您还可以镜像未加载的类(在注释处理期间的情况)或甚至远程图像中的类。 例如,V8(谷歌的Javascript引擎)使用镜像来调试在另一个对象空间中运行的Javascript代码。

本文可能有助于理解Java 6注释处理的设计:

Gilad Bracha和David Ungar。 镜像:面向对象编程语言的元级设施的设计原则。 在Proc。 ACM会议 面向对象编程,系统,语言和应用,2004年10月。