是否可以在运行时检查实现声明中的接口上是否存在 TYPE_USE 注释?

Is it possible to check at runtime whether or not a TYPE_USE annotation is present on an interface within a implements declaration?

考虑以下几点:

class A implements @X B, C, @X D {}

是否可以在运行时检索每个实现接口上的实现声明是否包含@X?

所以在上面的例子中,B 的答案是肯定的,C 不是,D 是的。

如果是,我将如何实现?

是的,这可以通过 Class#getAnnotatedInterfaces() 实现。

Returns an array of AnnotatedType objects that represent the use of types to specify superinterfaces of the entity represented by this Class object. (The use of type Foo to specify a superinterface in '... implements Foo' is distinct from the declaration of type Foo.)

[...]

例如:

package com.example;

import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedType;

import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

public class Main {

  public static void main(String[] args) {
    for (AnnotatedType type : A.class.getAnnotatedInterfaces()) {
      System.out.println(type.getType());
      for (Annotation annotation : type.getAnnotations()) {
        System.out.println("\t" + annotation);
      }
      System.out.println();
    }
  }

  @Retention(RUNTIME)
  @Target(TYPE_USE)
  @interface X {
    String value();
  }

  interface B {}
  interface C {}
  interface D {}

  static class A implements @X("Hello, ") B, C, @X("World!") D {}
}

输出:

interface com.example.Main$B
    @com.example.Main$X("Hello, ")

interface com.example.Main$C

interface com.example.Main$D
    @com.example.Main$X("World!")

其他类似的方法包括:

请注意 AnnotatedType 具有子类型,例如 AnnotatedParameterizedType。后一个接口让我们得到类型参数上的任何注释:

要知道 AnnotatedType 是否是子类型的实例,需要进行 instanceof 测试(除非您已经确定)。