背后的概念是什么:类型 – 元素 – 镜子
我正在使用Java 6的注释处理,即可以在javax.annotation.processing
(而不是Java 5的APT)中找到的内容。
我想知道各种Element
, Type
和Mirror
类之间的概念差异是什么。 由于我不太明白这一点,因此很难有效地编写注释处理器。 有各种方法可以在这些概念之间“转换”,但我不确定在使用它们时我在做什么。
所以,例如,让我有一个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月。