Class.getAnnotation(Class annotationClass) 用于获取类上直接声明的单个指定类型运行时注解实例,要求注解必须为 @Retention(RetentionPolicy.RUNTIME),且不搜索父类、接口或重复注解。

Class.getAnnotation(Class<t> annotationClass)</t> 是 Java 反射中获取类上**单个指定类型**的运行时注解实例的标准方法。它只返回该类**直接声明**(即源码中显式写在类定义上的)且 @Retention(RetentionPolicy.RUNTIME) 的注解,不搜索父类或接口,也不返回重复注解(如 @Repeatable 类型需用 getAnnotationsByType)。
确保注解满足运行时可见性
这是前提条件:注解本身必须用 @Retention(RetentionPolicy.RUNTIME) 声明,否则反射无法读取。
@Retention(RetentionPolicy.CLASS)
@interface MyAnnotation { String value() default ""; }
✔ 正确示例:
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation { String value() default ""; }
调用 getAnnotation 获取实例
直接传入目标注解的 Class 对象,返回对应注解实例(若存在),否则返回 null。
- 注解必须直接标注在该类上(不能仅继承自父类或实现的接口)
- 结果为
annotationClass类型的实例,可直接调用其方法(如value()) - 若类未声明该注解,返回
null,务必判空避免NullPointerException
示例:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
立即学习“Java免费学习笔记(深入)”;
public class UserService {}
@MyAnnotation("service")
public class UserServiceImpl extends UserService {}
// 获取注解
MyAnnotation ann = UserServiceImpl.class.getAnnotation(MyAnnotation.class);
if (ann != null) {
System.out.println(ann.value()); // 输出 "service"
}
注意继承与重复注解的限制
getAnnotation 不处理两种常见场景:
-
继承自父类/接口的注解:即使父类有
@MyAnnotation,子类调用getAnnotation返回null -
重复注解(@Repeatable):如
@RolesAllowed("ADMIN", "USER"),应改用getAnnotationsByType(RolesAllowed.class)获取数组
替代方案:需要向上查找父类注解?
Java 本身不提供自动继承查找,需手动遍历类层次结构:
public static <T extends Annotation> T findAnnotation(Class<?> clazz, Class<T> annType) {
while (clazz != null) {
T ann = clazz.getAnnotation(annType);
if (ann != null) return ann;
clazz = clazz.getSuperclass();
}
return null;
}
调用:findAnnotation(UserServiceImpl.class, MyAnnotation.class) —— 这样能查到父类上的注解。

















