java反射可获取方法注解值:先获method对象,再用getannotation()获取指定runtime注解实例并调用其属性方法;或用getdeclaredannotations()遍历所有显式声明注解,通过annotationtype()判断类型后强转解析。

Java 中可以通过反射获取方法上的注解,并进一步解析其值。核心步骤是:先获取 Method 对象,再调用 getAnnotation(Class) 或 getDeclaredAnnotations() 获取注解实例,最后通过注解的方法(即属性)读取值。
获取指定类型的注解
最常用方式是直接获取某个自定义或标准注解的实例,前提是该注解的 @Retention 为 RUNTIME(否则运行时不可见):
- 确保注解声明时使用
@Retention(RetentionPolicy.RUNTIME) - 使用
method.getAnnotation(YourAnnotation.class)获取注解对象 - 若注解不存在,返回
null,需判空处理
示例:
自定义注解@Retention(RetentionPolicy.RUNTIME)
public @interface ApiLog {
String value() default "";
boolean enabled() default true;
}
在方法上使用
public class UserService {
@ApiLog(value = "用户登录", enabled = true)
public void login(String username) { ... }
}
反射读取
Method method = UserService.class.getMethod("login", String.class);
ApiLog annotation = method.getAnnotation(ApiLog.class);
if (annotation != null) {
System.out.println(annotation.value()); // 输出:用户登录
System.out.println(annotation.enabled()); // 输出:true
}
获取所有注解(包括重复和元注解)
当需要检查多个注解、或不确定具体类型时,可用以下方式:
-
method.getDeclaredAnnotations():返回该方法**显式声明**的所有注解(不含继承的) -
method.getAnnotations():返回所有**可见**注解(含从接口/父类继承的,若注解标注了@Inherited且作用于类) - 对每个
Annotation实例,可用annotation.annotationType()判断类型,再强转解析
示例:
for (Annotation ann : method.getDeclaredAnnotations()) {
Class extends Annotation> type = ann.annotationType();
if (type == ApiLog.class) {
ApiLog log = (ApiLog) ann;
System.out.println("日志名:" + log.value());
} else if (type == Deprecated.class) {
System.out.println("该方法已弃用");
}
}
处理重复注解(Java 8+)
若注解支持重复(即标注了 @Repeatable),不能直接用 getAnnotation(),而应使用:
-
method.getAnnotationsByType(YourRepeatableAnnotation.class):返回所有同类型注解数组 -
method.getDeclaredAnnotationsByType(...):仅查当前声明,不包含继承
示例(重复注解):
@Repeatable(ApiLogs.class)
public @interface ApiLog {
String value() default "";
}
public @interface ApiLogs {
ApiLog[] value();
}
// 方法上用了两次 @ApiLog
@ApiLog("创建订单")
@ApiLog("发送通知")
public void process() { ... }
// 反射获取全部
ApiLog[] logs = method.getAnnotationsByType(ApiLog.class);
for (ApiLog log : logs) {
System.out.println(log.value());
}
注意事项与常见问题
- 反射获取注解前,必须确保类已被加载,且方法存在(注意拼写、参数类型匹配)
- 私有方法需先调用
method.setAccessible(true)才能访问(尤其配合getDeclaredMethod) - 泛型参数、桥接方法可能影响
getMethod查找,建议优先用getDeclaredMethod+ 显式设可访问 - Spring 等框架中,常结合 AOP 在代理对象上调用反射,此时需注意目标对象(target)而非代理对象
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











