Java注释反射排序

Gil*_*son 13 java reflection annotations

当通过反射访问在Field上定义的注释(即使用该getDeclaredAnnotations() : Annotation[]方法)时,Java 6或7规范对返回注释的顺序做出了任何保证.我已经检查了相关的java文档,但似乎无法找到明确的答案.

Hol*_*ger 14

这确实有点不明确.让我们从可重复注释的Java 8特性开始,因为它有一些关于它的部分:

JLS§9.7.5.多个相同类型的注释:

隐式声明的注释称为容器注释,并且T在上下文中出现的多个注释类型称为基本注释.value容器注释的(array-typed)元素的元素是它们在上下文中出现的从左到右顺序的所有基本注释.

因此容器将按顺序提供重复注释.

此外,文档AnnotatedElement指定:

为的调用get[Declared]AnnotationsByType( Class < T >),注释,它们可直接或间接地存在的元件上的顺序ë被计算为,如果间接地对本说明Ë直接存在于ê代替它们的容器注释的,在顺序它们出现在值容器注释的元素.

将这两者放在一起,就意味着重复的注释就像@Foo(1) @Foo(2) @Foo(3)你所写的一样存储@FooContainer({@Foo(1), @Foo(2), @Foo(3)}),后者,无论它最初是如何创建的,都将被视为getDeclaredAnnotations()直接呈现该命令的注释.

因此,重复注释的答案是订单将是"它们出现的从左到右的顺序".


但是我们可以从文档中得出另一个结论AnnotatedElement.由于它表明注释的顺序被计算为好像间接呈现的注释直接存在于其容器注释的位置,这意味着如果你写@Foo(1) @FooContainer({@Foo(2), @Foo(3)})或者@FooContainer({@Foo(1), @Foo(2)}) @Foo(3),订单将与容器的元素相同,将替换它就像你写过吗@Foo(1) @Foo(2) @Foo(3)

有趣的是,如何实现:

如果发现注释类型annotationClass的注释直接和间接存在,getDeclaredAnnotations()则将调用以确定返回数组中元素的顺序.

本实施说明是整个文档中getDeclaredAnnotations()具有可靠订单的第一个指标.它用于确定履行上述合同所需的订单.

所以答案是,是的,getDeclaredAnnotations()以有保证的顺序提供注释,但该信息不直接附加到方法本身的文档中.

这是从Java 8文档中获得的,但是由于Java 6和7现在已经到了生命周期并且不会改变,因此观察到的实现行为与至少对Java 8保证的行为相匹配这一事实,可能足够依赖它.

  • 我跟OpenJDK的一个贡献者谈过,他说这个官方应该没问题.所以我们将创建一个"规范请求",它有可能落在JDK.next中. (2认同)