@inherited仅使子类通过getannotation()获取父类类级别注解,需同时满足:注解自身声明@inherited、@target含elementtype.type、@retention为runtime;方法、字段、接口等场景均无效。

@Inherited 并不能让子类“自动拥有”父类的注解,它只是在特定条件下,允许 Class.getAnnotation() 方法沿继承链向上查找类级别的注解。用错场景,反射结果永远为 null。
只对类(ElementType.TYPE)生效
这是硬性前提。只有标注在类、接口、枚举上的注解,才可能被子类通过 getAnnotation() 获取到。
- 方法上加了
@Inherited的注解?子类重写该方法后,getMethod().getAnnotation()一定返回null - 字段、参数、构造器、局部变量上的注解?
@Inherited完全不参与处理 - 接口上定义了带
@Inherited的注解?实现类class Impl implements I不会继承它
三个条件必须同时满足
缺一不可,否则子类调用 getAnnotation() 就查不到。
- 自定义注解自身声明了
@Inherited -
@Target包含ElementType.TYPE -
@Retention是RetentionPolicy.RUNTIME
例如:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Inherited<br>public @interface Config { String value(); }
这样定义后,
@Config("a") class Parent {} → class Child extends Parent {} → Child.class.getAnnotation(Config.class) 才非空。
不覆盖、不组合、不跨接口
实际使用中容易踩坑的边界情况:
- 子类自己也写了
@Config,哪怕值不同,父类注解就被完全屏蔽 - 父类是通过 Spring 注解(如
@Service)间接获得的注解,而非直接声明,子类查不到 - 父类实现某个接口,接口上有注解 —— 这和
@Inherited无关,JVM 不支持接口注解向实现类传递
多层继承能查到,但不是“多级继承”
A → B → C 的继承链中,C 能拿到 A 的注解,不是因为 @Inherited 支持“跨两层”,而是因为 getAnnotation() 本身会递归查 getSuperclass(),一直找到 Object。只要中间任意一层(比如 B)自己声明了同名注解且该注解类型没加 @Inherited,那 C 就只能看到 B 的,拿不到 A 的。
真正需要跨层级、跨接口获取注解时,得自己写工具方法:遍历 getSuperclass() 和 getInterfaces(),逐个调用 getAnnotation() 判断。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











