java反射获取注解需注解声明@retention(retentionpolicy.runtime),否则运行时不可见;getannotation()返回指定注解实例或null;getannotations()返回所有显式声明的runtime注解数组;isannotationpresent()高效判断注解是否存在。

Java 通过反射获取类上的注解信息,核心是使用 Class 对象的 getAnnotation() 或 getAnnotations() 等方法,前提是注解本身必须用 @Retention(RetentionPolicy.RUNTIME) 声明,否则运行时不可见。
确保注解在运行时可用
只有声明为 RetentionPolicy.RUNTIME 的注解才能被反射读取。例如:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME) // 必须是 RUNTIME
public @interface MyClassAnnotation {
String value() default "";
int version() default 1;
}如果漏掉 @Retention(RetentionPolicy.RUNTIME),反射调用会始终返回 null。
获取单个注解(存在则返回,否则 null)
使用 clazz.getAnnotation(Class<t> annotationClass)</t> 获取指定类型的注解:
- 若类上标注了该注解,返回对应注解实例;
- 若未标注或注解不可见(如 retention 不是 RUNTIME),返回
null; - 不抛异常,适合安全判断。
示例:
@MyClassAnnotation(value = "Service", version = 2)
public class UserService { }
<p>// 反射获取
Class> clazz = UserService.class;
MyClassAnnotation ann = clazz.getAnnotation(MyClassAnnotation.class);
if (ann != null) {
System.out.println(ann.value()); // 输出 "Service"
System.out.println(ann.version()); // 输出 2
}</p>获取所有注解(包括元注解)
用 getAnnotations() 获取类上所有 **显式声明** 的、且保留策略为 RUNTIME 的注解(不含继承来的):
- 返回
Annotation[],可能为空数组(不是 null); - 包含重复注解(如果注解类型支持
@Repeatable); - 不包含从父类或接口继承的注解(Java 默认不继承注解)。
若需获取包括父类的注解,需手动遍历 clazz.getSuperclass() 并递归调用。
检查注解是否存在(布尔判断更简洁)
不用先取再判空,可直接用 isAnnotationPresent():
- 返回
boolean,语义清晰; - 性能略优(底层可能跳过实例化);
- 适合只关心“有没有”,不关心具体值的场景。
示例:
if (UserService.class.isAnnotationPresent(MyClassAnnotation.class)) {
System.out.println("UserService 被标记了 MyClassAnnotation");
}Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











