如何获取注解上方的注解
How to get the annotation above the annotation
我给方法加了注解,这个注解里还有其他的注解。当我尝试通过该方法获取上面的注释时,不幸的是,return 始终为 null。我想知道为什么?
这是我定义的方法
@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
时,结果总是 return 为 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()
来获取注释实例的 class,而不是 Object#getClass()
。后一种方法不会返回您认为的 class 。请尝试以下操作:
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 {}
Main.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!
如您所见,注释 实例 的 class 是一个代理 class,它不会包含您正在查询的注释。
我给方法加了注解,这个注解里还有其他的注解。当我尝试通过该方法获取上面的注释时,不幸的是,return 始终为 null。我想知道为什么?
这是我定义的方法
@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
时,结果总是 return 为 nullClass<?> 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()
来获取注释实例的 class,而不是 Object#getClass()
。后一种方法不会返回您认为的 class 。请尝试以下操作:
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 {}
Main.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!
如您所见,注释 实例 的 class 是一个代理 class,它不会包含您正在查询的注释。