跳到主要内容

JEP 120:重复注释

概括

更改 Java 编程语言,以允许将相同类型的注释多次应用到单个程序元素。

目标

提高源代码的可读性,源代码在逻辑上将相同注释类型的多个实例应用到给定的程序元素。

动机

在 EE 和其他地方使用注释进行编程时经常使用的习惯用法是笨拙地使用容器注释,只是为了模拟应用多个注释的能力。建立对重复注释的支持将提高源代码的可读性。

描述

实现该语言功能的基本方法是将基类型的重复注释脱糖为单个容器注释;容器注释有一个values方法,它返回基本注释类型的数组。要为特定注释类型启用重复注释,基本注释类型的声明将需要包含一个新的元注释,例如@ContainerAnnotation,以声明应将哪个其他注释类型用作容器。如果容器与基本注释不适合兼容,则应发出警告和错误,包括保留策略或目标中存在问题的差异。

开放设计问题包括是否支持多个级别的编译器生成的容器。例如,应该

@A(1)
@A(2)
@AContainer
@AContainerContainer
foo();

被视为逻辑上等同于

@AContainerContainer(@AContainer({@A(1), @A2}), @AContainer)
foo();

或一级嵌套后出现编译错误

@AContainer({@A(1), @A(2)})
@AContainer
@AContainerContainer
foo();

在库级别,平台中反射 API 的实现(包括核心反射和javax.lang.model)需要更新以处理重复的注释信息。例如,AnnotatedElement.getAnnotation(BaseAnnotation.class)如果基本注释不直接存在,则该方法将被重新定义以在容器注释中查找。可以向接口添加一种或多种查询注释存在或不存在的方法AnnotatedElement。如果支持多级编译器生成的嵌套,则库的更改将更加广泛。

测试

与所有语言更改一样,相应的编译器 JCK 测试也需要更新。

风险和假设

一个风险是该语言功能与现有库语义之间或该语言功能与 Java SE 8 中存在的其他语言功能之间可能存在当前不可预见的交互。特别是,重复注释与类型注释之间的交互(如果有)需要被定义。

假设使用手动容器注释模式的现有 EE 注释类型将迁移到使用重复注释模式,从而通过使用来验证该功能。

如果各种 Java IDE 在开发过程中不支持这种语言更改,则该功能的实验及其设计的验证将会减慢。

依赖关系

需要定义重复注释与JEP 104:Java 类型注释(如果有)之间的交互。

影响

  • 其他 JDK 组件:在 JDK 代码库中直接使用重复注释的情况预计会最少。

  • 兼容性:通常不希望在 JDK 之外实现的接口可能会添加方法。 Lambda 项目中的 Defender 方法可以帮助限制源兼容性影响。

  • 性能/可扩展性:如果不使用该功能,编译速度不应降低。