java - 类型嵌套时 TYPE_USE 注释丢失,通用接口(interface)

标签 java reflection annotations

<分区>

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

请观察下面的例子:

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 接口(interface)的每次使用中都可以正确检索注释。但是,在每次使用 Entry 接口(interface)时,无论是字段、返回类型还是参数,注释都会丢失。我对此的唯一解释是 Entry 接口(interface)嵌套在 Map 接口(interface)中。

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

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

最佳答案

这已在 SO: Why annotation on generic type argument is not visible for nested type? 中发现

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

不过,您可以使用 ByteBuddy解析字节码并检索带注释的类型。

ASM根据我的经验,它也可以工作,我怀疑任何字节码解析器都可以解决这个错误。

关于java - 类型嵌套时 TYPE_USE 注释丢失,通用接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42512701/

相关文章:

C# 反射从类型中获取对象

java - 反射 - 示例代码 - ClassNotFoundException 错误

swift - 在 swift 中向 MapKit 注释 View 添加操作

spring - 是否可以在 Spring、Eclipselink 和 Tomcat 环境中使用@Transational?

java - 如何从java文件中获取并显示两个字符串(模式)之间的多行

java - Querydsl 空安全串联

java - 如何注入(inject) SQL 命令以在 Java 中删除表

java - Spring MVC 验证错误消息

java - 在交付单个 jar 并使用反射时,如何避免在命令行中指定完全限定的类名?

python - 为什么 mypy 拒绝我的 "mixed union"类型声明?