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

查看:23
本文介绍了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 接口时,无论是字段、返回类型还是参数,注释都会丢失.我对此的唯一解释是Entry 接口嵌套在 Map 接口内.

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 也可以,根据我的经验,我怀疑任何字节码解析器都可以解决这个错误.

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

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

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