Java注释反射排序

时间:2015-01-21 12:18:38

标签: java reflection annotations

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

1 个答案:

答案 0 :(得分:11)

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

JLS §9.7.5. Multiple Annotations of the Same Type

  

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

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

此外,AnnotatedElement的文档指定:

  

对于get[Declared]AnnotationsByType( Class < T >)的调用,计算直接或间接存在于元素 E 上的注释的顺序,就像在 E 上间接呈现注释一样直接出现在 E 上,代替它们的容器注释,按它们出现在容器注释的value元素中的顺序。

将这两者放在一起,意味着像@Foo(1) @Foo(2) @Foo(3)一样存储重复的注释,就像你写的@FooContainer({@Foo(1), @Foo(2), @Foo(3)})一样,而后者,无论最初如何创建,都会被{{1}处理就像直接呈现那个顺序的注释一样。

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

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

有趣的是,how that is achieved

  

如果发现注释类型annotationClass的注释直接和间接存在,那么将调用@Foo(1) @Foo(2) @Foo(3)来确定返回数组中元素的顺序。

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

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

这是从Java 8文档中获得的,但是由于Java 6和7现在已经达到其生命周期的终止而不会发生变化,因此观察到的实现行为与至少保证的行为相匹配对于Java 8,可能足以依赖它。