Java注解订购的反思 [英] Java Annotations Reflection Ordering

查看:233
本文介绍了Java注解订购的反思的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当访问通过反射的一个字段定义的注释(使用 getDeclaredAnnotations即():注释[] 方法)并在Java 6或7规范做出的任何担保在返回的注释订单。我已经检查了相关的Java文档,但似乎无法找到一个明确的答案。


解决方案

这是确实有点得以确认。让我们先从注解重复了Java 8的功能,因为有一些比特一下:

JLS§9.7。 5。同类型的多个批注:


  

隐式声明的注释被称为的集装箱标注的,然后键入 T 出现于上下文的多个注释被称为注释基地的。 (数组类型)价值容器标注的元素是在左到右的顺序,他们出现在上下文中。在所有基本注释<元素/ p>

所以容器将提供重复标注秩序。

此外,的文件 AnnotatedElement中 指定:


  

有关 GET [声明] AnnotationsByType的调用(类&LT; T&GT;)注释这些都直接或间接的元素present的顺序电子的计算,如果间接上的电子present注释的直接到位的集装箱标注美元的电子点$ psent,在它们出现在容器注释元素的值的顺序。


把他们俩撮合在一起,它意味着重复标注如 @foo(1)@foo(2)@foo(3)存储就像你写 @FooContainer({@美孚(1),@foo(2),@foo(3)}),后者,不管它是如何被最初创建,将被处理 getDeclaredAnnotations()像直接$该命令的对$ psent注释。

因此​​,对于重复标注的答案是,为了将左到右的顺序他们出现。


但还有另外一个结论,我们可以从 AnnotatedElement中的文档借鉴。因为它指出注释的顺序计算,如果间接present注释直接$到位的容器注释的对$ psent,它意味着如果你写 @foo(1)@FooContainer ({@foo(2),@foo(3)}) @FooContainer({@美孚(1),@foo(2)})@foo(3 ),订货会作为容器的元素将取代它,就像你已经书写的同一 @foo(1)@foo(2)@foo(3)

有意思的是,<一个href=\"http://docs.oracle.com/javase/8/docs/api/java/lang/reflect/AnnotatedElement.html#getDeclaredAnnotationsByType-java.lang.Class-\"相对=nofollow>该如何实现:


  

如果发现注释类型annotationClass的标注直接既间接present,那么 getDeclaredAnnotations()将被调用,以确定元素的顺序在返回的数组。


这实现值得注意的是, getDeclaredAnnotations()有一个可靠的订单在整个文档中的第一个指标。它被用来确定需要履行上述合同的顺序。

因此​​,答案是肯定的, getDeclaredAnnotations()提供了有保证的顺序标注,但这些信息不直接连接方法本身的文档。

这是从Java 8文档导出,但自从Java 6和7达到了结束现在的生活,不会改变的,其实施的观察到的行为至少是保证的行为相匹配的事实对Java 8,可能足以依赖它。

When accessing Annotations defined on a Field via Reflection (i.e using the getDeclaredAnnotations() : Annotation[] method) does the Java 6 or 7 specification make any guarantees about the order in which the Annotations are returned. I have examined the relevant java docs but can't seem to find a definitive answer.

解决方案

That’s indeed a bit underspecified. Let’s start with the Java 8 feature of repeatable annotations as there are some bits about it:

JLS §9.7.5. Multiple Annotations of the Same Type:

The implicitly declared annotation is called the container annotation, and the multiple annotations of type T which appeared in the context are called the base annotations. The elements of the (array-typed) value element of the container annotation are all the base annotations in the left-to-right order in which they appeared in the context.

So the container will provide the repeated annotations in order.

Additionally, the documentation of AnnotatedElement specifies:

For an invocation of get[Declared]AnnotationsByType( Class < T >), the order of annotations which are directly or indirectly present on an element E is computed as if indirectly present annotations on E are directly present on E in place of their container annotation, in the order in which they appear in the value element of the container annotation.

Putting these two together, it implies that repeated annotations like @Foo(1) @Foo(2) @Foo(3) are stored like you had written @FooContainer({@Foo(1), @Foo(2), @Foo(3)}) and the latter, regardless of how it was originally created, will be treated by getDeclaredAnnotations() like directly present annotations of that order.

So the answer for repeated annotations is that the order will be the "left-to-right order in which they appeared".


But there is another conclusion we can draw from the documentation of AnnotatedElement. Since it states that the order of annotations is computed as if indirectly present annotations are directly present in place of their container annotation, it implies that if you write @Foo(1) @FooContainer({@Foo(2), @Foo(3)}) or @FooContainer({@Foo(1), @Foo(2)}) @Foo(3), the order will be the same as the elements of the container will replace it just as had you written @Foo(1) @Foo(2) @Foo(3).

It’s interesting, how that is achieved:

If annotations of the annotation type annotationClass are found to be both directly and indirectly present, then getDeclaredAnnotations() will get called to determine the order of the elements in the returned array.

This implementation note is the first indicator within the entire documentation that getDeclaredAnnotations() has a reliable order. It is used to determine the order that is required to fulfill the contract described above.

So the answer is, yes, getDeclaredAnnotations() provides the annotations in a guaranteed order, but that information is not directly attached to the documentation of the method itself.

This is derived from the Java 8 documentation, but since Java 6 and 7 reached their end-of-life now and won’t change, the fact that the observed behavior of the their implementation matches the behavior that is guaranteed at least for Java 8, might be enough to rely on it.

这篇关于Java注解订购的反思的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆