Java反射读取注解需注解声明@Retention(RUNTIME),否则运行时不可见;通过getAnnotation()获取单个注解,getDeclaredAnnotations()获取本类注解,getAnnotationsByType()处理可重复注解,并需异常处理与空值判断。

在 Java 中,可以通过反射机制获取类、方法、字段等元素上定义的注解,并读取其配置的元数据。关键在于使用 getAnnotation(Class 或 getDeclaredAnnotations() 等反射 API,同时确保注解本身具有合适的 @Retention(RetentionPolicy.RUNTIME),否则运行时无法访问。
确保注解支持运行时保留
只有声明了 @Retention(RetentionPolicy.RUNTIME) 的注解才能在运行时通过反射读取。若缺少该元注解,反射调用会返回 null 或空数组。
- 正确示例:
@Retention(RetentionPolicy.RUNTIME) // 必须
public @interface MyConfig {
String value() default "";
int version() default 1;
}
- 错误情况:若只写
@Retention(RetentionPolicy.CLASS)或未声明,默认为SOURCE,反射将不可见。
获取类上的注解实例并提取属性值
使用 Class.getAnnotation(Class) 获取指定类型的注解对象,再调用其方法读取元数据。
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- 示例代码:
public class UserService { }
// 反射读取
Class> clazz = UserService.class;
MyConfig anno = clazz.getAnnotation(MyConfig.class);
if (anno != null) {
System.out.println(anno.value()); // 输出 "service-v2"
System.out.println(anno.version()); // 输出 2
}
批量获取所有注解或处理重复注解
若需检查多个注解,可用 getAnnotations()(含继承)或 getDeclaredAnnotations()(仅本类声明)。对可重复注解(@Repeatable),应使用 getAnnotationsByType()。
-
clazz.getAnnotations():返回所有@Retention(RUNTIME)注解(包括父类/接口继承的) -
clazz.getDeclaredAnnotations():仅返回当前类显式声明的注解,不包含继承的 - 可重复注解示例:
@Retention(RetentionPolicy.RUNTIME)
public @interface MyConfig { ... }
@MyConfig("A") @MyConfig("B")
public class Service { }
// 正确获取多个实例:
MyConfig[] configs = clazz.getAnnotationsByType(MyConfig.class);
注意访问权限与异常处理
反射操作本身不抛出检查异常,但若类未加载、注解类型不可见或安全策略限制,可能触发 NoClassDefFoundError 或 SecurityException。生产环境建议包裹 try-catch 并做空值判断。
- 常见防护写法:
try {
anno = clazz.getAnnotation(MyConfig.class);
} catch (Exception e) {
// 记录日志,避免崩溃
log.warn("Failed to read @MyConfig on {}", clazz.getName(), e);
}
if (anno == null) return defaultValue;
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










