@inherited仅使类级注解在class.getannotation()中沿继承链向上查找一次,须同时满足:注解自身被@inherited修饰、@target(elementtype.type)、@retention(retentionpolicy.runtime)。

Java 中的 @Inherited 并不表示“子类自动拥有父类注解”,它只是一种反射查找机制的简化开关——仅在特定条件下,让 Class.getAnnotation() 沿继承链向上查找一次类级注解。
必须同时满足的三个条件
缺一不可,否则 @Inherited 完全不生效:
- 该注解自身被
@Inherited修饰(不能直接给类加@Inherited) - 该注解声明了
@Target(ElementType.TYPE),且只能用于标注类 - 该注解声明了
@Retention(RetentionPolicy.RUNTIME),确保运行时可读取
它只对类有效,其他地方一律无效
很多误用源于对作用范围的误解:
- 父类方法上的注解,哪怕带
@Inherited,子类调用getMethod().getAnnotation()一定返回null - 接口上定义的注解,实现类不会继承;哪怕接口注解也用了
@Inherited,照样无效 - 字段、构造器、参数、局部变量等位置的注解,
@Inherited对它们无任何影响 - 若父类是通过组合(如 Spring 的
@Service)间接获得注解,而非直接声明,子类查不到
真正生效时的行为表现
假设定义如下注解:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyConfig { String value() default ""; }
并这样使用:
@MyConfig("parent")
class Parent {}
class Child extends Parent {}
此时:
-
Child.class.getAnnotation(MyConfig.class)返回非空(值为"parent") -
Child.class.getDeclaredAnnotation(MyConfig.class)仍返回null(子类未显式声明) - 多层继承也支持:A → B → C,C 调用
getAnnotation()可拿到 A 上的@MyConfig
想查方法或字段的“继承注解”?得手动遍历
Java 原生不提供跨层级的方法/字段注解继承查找:
- 要获取“继承链上最近的方法注解”,需从目标类开始,调用
getDeclaredMethod()查当前类声明的方法 - 若没找到,再调用
getSuperclass()获取父类,重复查找 - 如需支持接口,还要额外处理
getInterfaces()并递归其父接口(注意避免循环) - Spring 的
AnnotationUtils.findAnnotation()就是这样实现的
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











