JEP 119:核心反射支持的 javax.lang.model 实现
概括
提供javax.lang.model.*
由核心反射而不是javac
.换句话说,提供一个备用 API 来访问和处理由核心反射提供的有关加载类的反射信息。
目标
提供统一的 API 来查看有关类型及其成员的编译时和运行时反射信息。降低与注释相关的语言功能的实验障碍。
动机
核心反射 API 有各种设计限制;有关详细信息,请参阅镜像:面向对象编程语言的元级设施的设计原则。
该javax.lang.model.*
API 用于javac
提供注释处理支持;然而,javax.lang.model.*
API 并不限于在编译时对 Java 结构进行建模。
如果存在javax.lang.model.*
由核心反射支持的实现,则可以使用相同的代码来分析类型的编译时和运行时视图。此外,由于javax.lang.model.*
它基于接口,因此可以使用运行时模型的专门化来允许更轻松地进行替代注释语义的实验。
例如,一些团体主张更改语言的注释工具以支持_刻板印象_,其中单个注释的应用在逻辑上可以扩展到一组其他注释。要在运行时通过核心反射支持此类功能,需要更改 和javac
核心反射中的至少一项,以便可以执行扩展。给定 的适当实现javax.lang.model.*
,该方法的次要专业化getAnnotation
可用于实现构造型或各种其他替代注释语义,而无需修改平台的核心方面。
描述
预期的实现方法是提供一组工厂方法,这些方法用实现相应javax.lang.model.*
构造的适配器包装核心反射对象。例如,一个方法在呈现对象时java.lang.reflect.Method
将返回javax.lang.model.element.ExecutableElement
具有某种类型METHOD
和匹配名称等的对象,对于其他语言结构也是如此。这种方法显然是可行的,概念验证实施进展顺利,但关于设计和实施存在几个悬而未决的问题:
-
API 应该是 JDK 特定的还是 Java SE 的一部分?
-
为了专业化,应该公开多少实现?
-
javax.lang.model.*
是否应该更新标准以更好地支持此用例?严格来说,特定要求javax.lang.model.*
仅适用于 API 用于 注释处理时。 -
是否应该提供特定于运行时的 API 专门化
javax.lang.model.*
来访问核心反射特定功能(例如调用方法)?
测试
测试实现的主要挑战javax.lang.model.*
不是测试所有方法本身,而是在所有不同类型的语言结构上测试所有方法。语言模型 API 的底层结构是被建模的语言。例如,要彻底测试(例如)getModifiers
方法,应探查可以具有修饰符(类型、变量、参数等)的每种元素,以查找对于该种元素合法的每组修饰符,甚至对于这个简单的行为有几十种组合。
风险和假设
核心反射(从根本上提供了 JVM 级世界视图)与纯语言模型之间的阻抗不匹配可能会使实现变得复杂。专门用于核心反射的 API 的动机之一是合理地处理合成结构,根据定义,这些合成结构超出了纯语言模型的范围。
依赖关系
对核心反射 API 的各种调整(其中一些已在 JDK 8 版本中进行)将简化实现javax.lang.model.*
。例如,新的Executable
超类可以Method
简化Constructor
代码共享。
假设实现了对方法/构造函数参数名称的运行时访问,该项目是这些设施的自然客户端。
影响
-
javax.lang.model.*
兼容性:核心反射支持的行为和javac
. -
安全性:将使用核心反射的底层安全机制。
-
TCK:如果此 API 作为 Java SE 的一部分提供,则 JSR 269 的一些 JCK 测试可能能够适应测试该 API。