java反射可通过getannotation()获取类上runtime保留策略的指定注解对象并调用其属性方法读值;可用annotationtype().getdeclaredmethods()遍历所有属性;重复注解需用getannotationsbytype()获取数组。

Java 反射可以获取类、方法、字段等元素上的注解,并读取其属性值,关键在于使用 getAnnotation(Class<t>)</t> 或 getDeclaredAnnotations() 方法,再通过注解对象的默认方法(即属性)直接调用获取值。
获取类上的指定注解对象
使用 Class.getAnnotation(Class<t>)</t> 获取标注在类上的某个具体注解(只找该类型,且要求是 @Retention(RetentionPolicy.RUNTIME)):
- 注解必须声明为
@Retention(RUNTIME),否则反射无法读取 - 如果类没加该注解,返回
null,记得判空 - 示例:假设有个自定义注解
@MyConfig(value="app", version=2)
@MyConfig(value = "web", version = 3)
public class UserService { }
反射获取方式:
Class> clazz = UserService.class;
MyConfig anno = clazz.getAnnotation(MyConfig.class);
if (anno != null) {
String value = anno.value(); // → "web"
int version = anno.version(); // → 3
}
读取注解中所有属性值(通用方式)
若想动态遍历注解所有属性(不硬编码属性名),可把注解对象转为 java.lang.reflect.InvocationHandler 或用 Annotation#annotationType().getDeclaredMethods() 遍历方法:
- 每个注解属性对应一个无参方法,返回值即属性值
- 方法名就是属性名,可通过
method.invoke(annotation)调用 - 注意:方法需设为可访问(
setAccessible(true))
MyConfig anno = clazz.getAnnotation(MyConfig.class);
if (anno != null) {
for (Method m : anno.annotationType().getDeclaredMethods()) {
try {
m.setAccessible(true);
Object val = m.invoke(anno);
System.out.println(m.getName() + " = " + val);
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 输出:value = web,version = 3
获取重复注解(@Repeatable)
从 Java 8 开始支持重复注解,需用 getAnnotationsByType() 替代 getAnnotation():
- 被
@Repeatable(Container.class)标记的注解,可用getAnnotationsByType(MyAnn.class)获取数组 -
getAnnotation()只返回第一个(或 null),不适用于重复场景
@MyAnn("a") @MyAnn("b")
public class Service { }
// 正确获取多个
MyAnn[] annos = Service.class.getAnnotationsByType(MyAnn.class);
for (MyAnn a : annos) {
System.out.println(a.value()); // → "a", "b"
}
注意事项和常见坑
实际使用中容易忽略的细节:
- 注解接口里属性不能有参数,不能有异常,不能有方法体(只能是 public abstract 方法)
- 属性默认值要用
default关键字声明,未赋值时取默认值 - 数组类型属性返回的是副本,修改它不影响原始注解
- 泛型、Class 类型、枚举、注解类型属性均可正常获取,但 Class 属性返回的是运行时
Class对象
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











