java - 如何获取注解上方的注解

标签 java reflection annotations

我给方法加了一个注解,这个注解里面还有其他的注解。当我尝试通过方法获取上面的注释时,不幸的是,返回始终为空。我想知道为什么?

这是我定义的方法

@ApiTest
public void add() {
}

这是我定义的注解。

@ValueName("hello word")
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ApiTest {

}
////////////////////////////////////////////////////////
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ValueName {
  String value() default "";
}

当我尝试获取@ValueName 时,结果总是返回null

Class<?> testApi = Class.forName("com.huawei.netty.TestApi");
    Method add = testApi.getMethod("add", null);
    ApiTest apiTest = add.getDeclaredAnnotation(ApiTest.class);
    ValueName valueName = apiTest.getClass().getDeclaredAnnotation(ValueName.class);
    if (valueName != null) {
      System.out.println(valueName.annotationType());
    }

但是这种方式可以获得

Class<?> apiTest = Class.forName("com.huawei.netty.ApiTest");
    ValueName valueName = apiTest.getDeclaredAnnotation(ValueName.class);
    if (valueName != null) {
      System.out.println(valueName.value());
    }

我能知道这是为什么吗?

最佳答案

你应该使用 Annotation#annotationType()获取注释实例的类,而不是 Object#getClass()。后一种方法不会返回您认为的类。尝试以下操作:

MetaAnnotation.java

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface MetaAnnotation {

    String value();

}

CustomAnnotation.java

@MetaAnnotation("Hello, World!")
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface CustomAnnotation {}

主.java

@CustomAnnotation
public final class Main {

    public static void main(String[] args) {
        CustomAnnotation ca = Main.class.getAnnotation(CustomAnnotation.class);
        MetaAnnotation   ma = ca.annotationType().getAnnotation(MetaAnnotation.class);

        System.out.println("CustomAnnotation#getClass()       = " + ca.getClass());
        System.out.println("CustomAnnotation#annotationType() = " + ca.annotationType());
        System.out.println("MetaAnnotation#value()            = " + ma.value());
    }

}

当我使用 OpenJDK 12.0.1 运行上面的代码时,我得到以下输出:

CustomAnnotation#getClass()       = class com.sun.proxy.$Proxy1
CustomAnnotation#annotationType() = interface CustomAnnotation
MetaAnnotation#value()            = Hello, World!

如您所见,注解类实例是一个代理类,它不会有您正在查询的注解。

关于java - 如何获取注解上方的注解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57238406/

相关文章:

java - 如何在 Spring Sleuth 中的响应式(Reactive)调用链中命名 Span

java - oracle.sql.DATUM 已弃用。它的替代品是什么?

从 main 访问 Java 类

java - 为什么将 Joda DateTime 转换为 Calendar 并返回会更改 centuryOfEra 字段而不是其他任何内容?

c# - 如何在运行时加载的程序集中使用公共(public) log4net 引用?

java - 注释处理器是否可以访问上一轮生成的类型?

javascript - 在 Acrobat JS API 中将透明颜色设置为 strokeColor 会导致黑色边框

C# - 从子类中获取属性值

java - 创建通用 JavaBean 构建器

1.3 版不支持 java 泛型和注释(travis 集成)