java反射获取注解中class属性需先获取注解实例再调用对应方法,支持class、class等类型,但泛型信息在运行时被擦除,仅能获得原始class对象。

Java 中通过反射获取注解里定义的 Class 类型属性,核心是先获取注解实例,再调用其对应的方法(该方法返回 Class 对象)。只要注解中声明了 Class 类型的元素,并在目标类/方法/字段上正确使用,就能安全读取。
确认注解定义支持 Class 类型属性
注解中必须显式声明一个返回 Class 的方法(不能是 Class> 以外的泛型擦除形式,但 Class>、Class<string></string> 等均可):
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
Class> value() default Object.class;
Class<string> stringClass() default String.class;
Class[] classes() default {};
}
</string>
在目标位置使用该注解
比如加在类上(也可用于方法、字段等),并传入具体的 Class:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
@MyAnnotation(value = List.class, stringClass = Integer.class)
public class UserService {
}
通过反射读取 Class 属性值
获取类对象后,拿到注解实例,直接调用方法即可。注意:返回值就是运行时真实的 Class 对象,可直接用于 newInstance、isAssignableFrom、getDeclaredMethods 等操作:
- 获取单个
Class属性:annotation.value()或annotation.stringClass() - 获取
Class[]数组:annotation.classes(),遍历每个元素都是Class - 确保注解保留策略为
RUNTIME,否则反射无法读取 - 调用前建议判空或捕获
NullPointerException(若注解未添加到目标上,getAnnotation()返回 null)
Class> clazz = UserService.class;
MyAnnotation ann = clazz.getAnnotation(MyAnnotation.class);
if (ann != null) {
Class> valueClass = ann.value(); // → List.class
Class<string> strClass = ann.stringClass(); // → Integer.class
Class[] classArray = ann.classes(); // → []
}
</string>
处理泛型 Class(如 Class extends Number>)的注意事项
Java 注解不支持带具体泛型实参的 Class 字面量(如 List<string>.class</string> 是非法语法),所以注解中只能写原始类型或通配符形式(如 Class extends Number>)。反射读出来的是擦除后的 Class,即 Number.class,泛型信息在运行时不可见:
-
@MyAnnotation(value = Integer.class)→ 反射得到Integer.class,不是Class extends Number> - 若需保留泛型语义,应改用
Type+ 自定义解析,或借助额外字符串配置(如类名 + 泛型描述)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










