跳到主要内容

JEP 119:由核心反射支持的 javax.lang.model 实现

QWen Max 中英对照

概述

提供一个由核心反射(core reflection)而非 javac 支持的 javax.lang.model.* 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 被用于注解处理时适用。
  • 是否应提供 javax.lang.model.* API 的运行时特定专门化,以访问核心反射特定功能,比如调用方法?

测试

测试 javax.lang.model.* 实现的主要挑战并不在于测试所有的方法本身,而在于测试所有不同语言结构上的所有方法。语言模型 API 的底层结构是被建模的语言。例如,为了彻底测试 getModifiers 方法,应该对每种可以具有修饰符的元素(类型、变量、参数等)进行探测,并针对该类元素合法的所有修饰符组合进行测试,即使对于这种简单的行为,也存在数十种组合。

风险与假设

核心反射与纯粹的语言模型之间存在阻抗不匹配,核心反射从根本上提供了 JVM 级别的世界观,而这种不匹配可能会使实现变得复杂。为核心反射设计专用 API 的一个动机是合理处理合成结构,因为根据定义,这些结构超出了纯粹语言模型的范畴。

依赖

对核心反射 API 的各种调整(其中一些已经在 JDK 8 构建中完成)将会简化 javax.lang.model.* 的实现。例如,新的 Executable 作为 MethodConstructor 的超类,便于代码共享。

假设运行时访问方法/构造函数参数名称已实现,该项目是这些功能的天然客户端。

影响

  • 兼容性:由核心反射支持的 javax.lang.model.* 和由 javac 支持的 javax.lang.model.* 在行为上会存在各种差异。
  • 安全性:将使用核心反射的底层安全机制。
  • TCK(技术兼容性套件):如果此 API 作为 Java SE 的一部分发布,JSR 269 的某些 JCK 测试可能能够被调整以测试该 API。