我正在使用Java 6的注释处理,即在javax.annotation.processing
(而不是Java 5的APT)中可以找到的内容。
我想知道各种Element
,Type
和Mirror
类之间的概念差异是什么。由于我不太了解这一点,因此很难有效地编写注释处理器。有很多方法可以在这些概念之间进行“转换”,但我不确定在使用它们时我在做什么。
所以,例如,让我有一个AnnotationMirror
的实例
当我致电getAnnotationType()
时,我得到DeclaredType
的实例(由于某种原因实现TypeMirror
)。
然后我可以在这个上调用asElement()
并获得Element
的实例
发生了什么事?
答案 0 :(得分:20)
这些概念确实存在重叠。
Element
模拟程序的静态结构,即包,类,方法和变量。想想你在Eclipse的包浏览器中看到的所有内容。
Type
模拟程序的静态定义类型约束,即类型,泛型类型参数,泛型类型通配符。只需考虑Java类型声明中的所有内容。
Mirror
是Gilad Bracha和Dave Ungar最初为Self开发的一种替代概念,Self是一种基于原型的Smalltalk方言。基本思想是从域对象中分离关于代码结构的查询(以及结构的运行时操作,以及Java中不可用的)。因此,要查询对象的方法,而不是调用#getClass
,您可以向系统询问镜像,通过该镜像可以看到对象的反射。由于这种分离,您还可以镜像未加载的类(在注释处理期间的情况)或甚至远程图像中的类。例如,V8(谷歌的Javascript引擎)使用镜像来调试在另一个对象空间中运行的Javascript代码。
答案 1 :(得分:5)
javax.lang.model.element.AnnotationMirror
类型的对象代表代码中的注释。
声明的类型表示注释类。
它的元素是泛型类(有关该问题的更多信息,请参阅http://java.sun.com/javase/6/docs/api/javax/lang/model/element/TypeElement.html)。该元素可能是类的通用版本,如List
,其中声明的类型是参数化版本,例如List<String>
。但是我不确定注释类是否可以使用泛型,因此在这种情况下区别可能是无关紧要的。
例如,假设您有以下JUnit4方法:
@Test(expected = MyException.class)
public void myTest() {
// do some tests on some class...
}
AnnotationMirror代表@Test(expected = NullPointerException.class)
。声明的类型是org.junit.Test
类。元素或多或少与没有涉及泛型的元素相同。
答案 2 :(得分:5)
本文可能有助于理解Java 6注释处理的设计:
Gilad Bracha和David Ungar。 Mirrors: Design Principles for Meta-level Facilities of Object-Oriented Programming Languages.在Proc。的 ACM会议面向对象 编程,系统,语言和 申请,2004年10月。