什么是“Type - Element - Mirror”背后的概念?

25

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

我想知道各种Element、Type和Mirror类之间的概念差异。由于我不太理解这个,因此很难高效地编写注解处理器。有一些 '转换' 这些概念的方法,但是当我使用它们时,我并不真正了解自己在做什么。

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

3个回答

29

这些概念确实有重叠之处。

  • Element 模型表示程序的静态结构,例如包、类、方法和变量。可以将其想象为 Eclipse 的包资源管理器中所看到的所有内容。

  • Type 模型表示程序的静态定义类型约束,例如类型、泛型类型参数、泛型类型通配符。可以将其想象为 Java 类型声明中的所有部分。

  • Mirror 是 Gilad Bracha 和 Dave Ungar 针对 Self(一种基于原型的 Smalltalk 方言)最初开发的反射替代概念。其基本思想是将代码结构的查询(以及运行时结构的操作 - 不幸的是在 Java 中不可用)与领域对象分离。因此,如果要查询一个对象的方法,您会向系统请求一个镜像,通过该镜像您可以看到对象的反射。由于这种分离,您还可以逆映射未加载的类(例如在注释处理期间),甚至是远程镜像中的类。例如,V8(谷歌的 JavaScript 引擎)在调试运行在另一个对象空间中的 JavaScript 代码时使用 mirrors。


2
理解这一点“您还可以在未加载的类上进行镜像(在注释处理期间是这种情况)”真的帮助我使用注释处理器。 - Guillaume

7

那么,我们是否有基于镜像的反射API,而不是传统反射系统中的getClass之类的反射API? java.lang.model.element.AnnotationMirror是否类似于ClassMirror(如本文所述)? - overexchange

6

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类。元素与其大致相同,因为没有涉及泛型。


Javadoc并没有很清楚地说明TypeElement是什么。我认为它更多地与类型的声明(因此类型参数)相关,而TypeDeclaration(令人困惑的名称)则更多地与类型的使用相关,例如在变量声明中。我认为这两个术语在注释的上下文中很难理解。 - Wolfgang
但是根据这个问题DeclareType必须是MyException.class - overexchange

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接