当类型是嵌套的通用接口时,TYPE_USE注释会丢失 [英] TYPE_USE annotations get lost when type is nested, generic interface

查看:144
本文介绍了当类型是嵌套的通用接口时,TYPE_USE注释会丢失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当带注释的类型是嵌套的通用接口时,似乎无法通过反射访问TYPE_USE注释。

It appears that TYPE_USE annotations cannot be accessed through reflection when the annotated type is a nested, generic interface.

请注意以下示例:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;
import java.util.Map.Entry;

public class LostAnnotation {
  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.TYPE_USE)
  public @interface SomeTypeAnnotation {
  }

  @SomeTypeAnnotation Map<String, String> map;
  @SomeTypeAnnotation Entry<String, String> entry;

  public static @SomeTypeAnnotation Entry<String, String> someMethod(
      @SomeTypeAnnotation Map<String, String> map,
      @SomeTypeAnnotation Entry<String, String> entry) {
    return null;
  }

  public static void main(String[] args) throws Exception {
    Class<LostAnnotation> clazz = LostAnnotation.class;
    Method method = clazz.getMethod("someMethod", Map.class, Entry.class);
    AnnotatedType[] types = method.getAnnotatedParameterTypes();

    print("map field", clazz.getDeclaredField("map").getAnnotatedType());
    print("map parameter", types[0]);

    print("entry field", clazz.getDeclaredField("entry").getAnnotatedType());
    print("entry parameter", types[1]);
    print("entry return type", method.getAnnotatedReturnType());
  }

  static void print(String title, AnnotatedType type) {
    System.out.printf("%s: %s%n", title, Arrays.asList(type.getAnnotations()));
  }
}

预期输出上面的代码是

map field: [@LostAnnotation$SomeTypeAnnotation()]
map parameter: [@LostAnnotation$SomeTypeAnnotation()]
entry field: [@LostAnnotation$SomeTypeAnnotation()]
entry parameter: [@LostAnnotation$SomeTypeAnnotation()]
entry return type: [@LostAnnotation$SomeTypeAnnotation()]

但是,上述代码的实际输出

map field: [@LostAnnotation$SomeTypeAnnotation()]
map parameter: [@LostAnnotation$SomeTypeAnnotation()]
entry field: []
entry parameter: []
entry return type: []

Map 界面的每次使用中都可以正确检索注释。但是,在每次使用 Entry 界面时,无论是字段,返回类型还是参数,注释都会丢失。我对此的唯一解释是条目界面嵌套在 地图 interface。

The annotation is correctly retrieved from every usage of the Map interface. However, on every usage of the Entry interface, be it field, return type or parameter, the annotation is lost. The only explanation that I have for this is that the Entry interface is nested inside the Map interface.

我在win64上的最新oracle JDK(8u121)上运行了上面的例子。我做错了什么或者这可能是个错误吗?

I ran the above example on the newest oracle JDK (8u121) on win64. Am I doing something wrong or could this be a bug?

我的注释是为了便于阅读而嵌套的。使其成为顶级界面不会改变任何内容。

推荐答案

这已经在 SO:为什么泛型类型参数的注释不是嵌套类型可见吗?

答案是错误已提交但优先级较低,因为这些情况不会经常出现。

Answer is bug has been submitted but in lower priority as those cases do not appear frequently.

但是,您仍然可以使用 ByteBuddy 来解析字节码并检索字节码带注释的类型。

Still, you can use ByteBuddy to parse the bytecode and retrieve the annotated type.

ASM 也适用于我的经验,我怀疑任何字节码解析器都可以解决这个bug。

ASM works too, from my experience, and I suspect any bytecode parser would work around this bug.

这篇关于当类型是嵌套的通用接口时,TYPE_USE注释会丢失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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