JEP 104:类型注解
概述
扩展 Java 编程语言语法中可注解位置的集合,以包括指示类型使用(以及(自 Java SE 5.0 起)类型声明)的名称。
目标
允许开发有用的可插拔类型检查器,以完善 Java 的内置类型系统。
非目标
可插拔类型检查器的标准化。
成功指标
- 三个基于 Java SE 8 构建的主要可插拔类型检查器,使用诸如 Ernst 的“Checker Framework”之类的框架。
- 可能会将至少一种注解方案(例如,用于控制空值)应用于 JDK 8 代码库的某些部分。这可能(或者可能不会)需要在 Java SE 中标准化有用注解类型(例如
@Nullable
)的定义。
动机
Java 的注解系统无疑是非常成功的。程序员可以在变量、方法和类的声明中为类型名称编写注解,然后由企业框架读取这些注解以用于配置目的,或者由编译器/IDE 用于软件质量目的。注解可以减少代码中的样板代码,并能够在编译时检测到基本错误。
对类型使用的注解而不仅仅是类型声明的注解,使得“可插拔类型检查器”能够检测错误,这增强了并细化了 Java 的内置类型系统。强化后的类型系统可以在编译时防止那些否则会在运行时出现的软件质量错误。示例包括空指针错误、对不可变数据的副作用、竞争条件、信息泄露以及未国际化的字符串。
描述
JSR 308 对 Java 语言的语法进行了有针对性的、低级别的修改,以允许在大多数可以使用类型名称的地方对类型名称进行注解。这包括出现在 Java SE 7 语言结构中的类型名称,例如 try-with-resources 和多捕获(multi-catch)。
JSR 308 定义了 JVM 类文件格式的新属性,以在类型名称上存储这些注解。最后,它对 java.lang.reflect
和 javax.lang.model
API 做出了有针对性的更改,以便可以检索特定类型名称实例上的注解。
替代方案
- 像 FindBugs 这样的工具可以在没有程序员提供注解的情况下评估惯用的编译时软件质量。
- 暗示注解的符号可以放置在 /* */ 样式的注释中,与类型名称相邻,从而“隐藏”语言本身的“注解”。这增加了视觉混乱,仍然需要 class 文件和反射更改。
测试
- JCK 测试针对 Java 语言中新可注解的结构、新生成的高于方法体级别的注解结构的类文件属性,以及新的反射 API。
- SQE 测试针对低于方法体级别的注解结构的新生成的类文件属性。(方法体编译是编译器特定的,因此未标准化,所以方法体内的结构上的注解不在 JCK 的范围内。)
- SQE 测试可以在单独的可插拔类型检查器上进行,但它们不是 JDK 8 或 Java SE 8 的一部分。
风险与假设
- 风险:广泛的 Java 开发社区对开发或使用可插拔类型系统不感兴趣。
- 假设:可插拔类型检查的实用性值得对 Java 语法、类文件和 API 进行重大更改。(除了在类型使用上的注解外,JSR 308 还改进了在类型声明上的注解,这些改进按照普遍共识本应在 JSR 175 中完成。这些改进本身并不能证明或预测 JSR 308 中更广泛的变化,但同样地,没有 308 的“支持”,这些改进也不太可能发生。)
影响
- 其他 JDK 组件:如果为特定 Checker 注解。
- 兼容性:任何 Java 语言或类文件解析器。
- 文档:javadoc 必须显示类型使用的注解。
- TCK:语言、类文件和反射更改。