@Inherited仅沿类继承链向上查找类级注解,不适用于接口实现、方法、字段等;生效需同时满足:注解标有@Inherited、@Target含TYPE、@Retention为RUNTIME、查询目标为Class且子类未声明同名注解。

@Inherited 不会让注解“自动出现在子类上”,它只改变 getAnnotations() 的查找路径——仅沿 extends 链向上搜索类级注解,对 implements 完全无效。这是 JVM 反射层的行为约定,不是编译器复制或运行时注入。
类继承中 @Inherited 生效的条件
必须同时满足以下四点,子类调用 getAnnotation(YourAnno.class) 才能拿到父类的注解:
- 注解本身被
@Inherited标记 - 该注解的
@Target包含ElementType.TYPE - 该注解的
@Retention是RUNTIME - 查询目标是类(
Class对象),且子类自身未声明同类型注解
接口实现不触发 @Inherited 查找
即使接口上的注解也加了 @Inherited,实现类调用 getAnnotations() 也查不到。JVM 反射不会检查 getInterfaces() 返回的接口链,只走 getSuperclass() 单向继承路径。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 接口 A 声明
@ApiVersion("2.0")并标注@Inherited - 类 B
implements A,但B.class.getAnnotation(ApiVersion.class)返回null - 若需支持,得手动遍历
clazz.getInterfaces()及其父接口递归查找
方法、字段等元素不参与 @Inherited 机制
@Inherited 对非类级目标无意义,哪怕注解定义时允许标注方法,只要它没被用于类上,继承逻辑就不会启动。
立即学习“Java免费学习笔记(深入)”;
- 父类方法加
@Deprecated(内部用了@Inherited),子类重写后调用getMethod().getAnnotation(Deprecated.class)拿不到 - 注解用在参数、局部变量、包声明上,
@Inherited完全不起作用 - 子类自己在方法上加同名注解,和父类方法注解无关,不存在覆盖或继承关系
替代方案:手动扫描接口注解
要让“接口声明的注解”对实现类可见,只能编码实现查找逻辑:
- 调用
clazz.getInterfaces()获取直接实现的接口数组 - 对每个接口,用
iface.getAnnotation(MyAnno.class)尝试获取 - 若未找到,递归调用
iface.getInterfaces()检查父接口(注意避免循环) - Spring 的
@Transactional在接口方法上生效,正是基于类似机制

















