如何通过@Inherited注解了解注解在子类中的继承行为?
- 内容介绍
- 相关推荐
本文共计712个文字,预计阅读时间需要3分钟。
要理解`@Inherited`在子类中的表现,首先需要明白它注解的继承特性。关键不在于加了就能用,而在于清晰它生效的条件和实际表现形式。`@Inherited`标记了某个属性或方法在子类中是继承自父类的,而不是子类自己定义的。它不改变字节码,仅影响反射行为。
简单来说,`@Inherited`用于表明子类中的属性或方法是如何从父类继承来的,而不是子类本身定义的。它不直接导致功能可用,而是反映了继承关系的存在。
注解必须是类级别且运行时可见
@Inherited 只对作用在类上的注解起作用,且该注解自身必须同时满足:
- @Target(ElementType.TYPE):只能标注在类、接口、枚举等类型上,不能标在方法或字段上
- @Retention(RetentionPolicy.RUNTIME):必须保留到运行期,否则 Class.getAnnotation() 根本查不到
子类“继承”只是反射查找路径的延伸
子类 class 文件里并不会多出任何注解信息。所谓“继承”,是指调用以下方法时 JVM 自动向上遍历父类:
- getAnnotations():返回当前类 + 父类中所有被 @Inherited 修饰的运行时注解
- isAnnotationPresent(YourAnno.class):返回 true,哪怕子类没显式声明
- getAnnotation(YourAnno.class):能拿到父类上定义的注解实例
但 getDeclaredAnnotations() 始终只返回子类自己声明的注解,完全不查父类。
哪些情况完全不生效
@Inherited 的限制非常明确,以下场景一律无效:
- 注解标在方法、字段、参数或局部变量上——哪怕加了 @Inherited,子类重写方法也拿不到父方法的注解
- 类实现接口:接口上的 @Inherited 注解,实现类无法通过反射获取
- 接口之间extends:子接口不会继承父接口的任何注解
- 注解的 @Retention 是 SOURCE 或 CLASS:运行时反射不可见,继承性无从谈起
多层继承也支持,但仅限直接 extends 链
只要继承链是单根的(A → B → C),C 类调用 getAnnotation() 仍能拿到 A 类上被 @Inherited 修饰的注解。这说明 JVM 查找时会一直向上直到 Object,而不是只看直接父类。但要注意,这种查找只走 extends 路径,不走 implements 或组合关系。
本文共计712个文字,预计阅读时间需要3分钟。
要理解`@Inherited`在子类中的表现,首先需要明白它注解的继承特性。关键不在于加了就能用,而在于清晰它生效的条件和实际表现形式。`@Inherited`标记了某个属性或方法在子类中是继承自父类的,而不是子类自己定义的。它不改变字节码,仅影响反射行为。
简单来说,`@Inherited`用于表明子类中的属性或方法是如何从父类继承来的,而不是子类本身定义的。它不直接导致功能可用,而是反映了继承关系的存在。
注解必须是类级别且运行时可见
@Inherited 只对作用在类上的注解起作用,且该注解自身必须同时满足:
- @Target(ElementType.TYPE):只能标注在类、接口、枚举等类型上,不能标在方法或字段上
- @Retention(RetentionPolicy.RUNTIME):必须保留到运行期,否则 Class.getAnnotation() 根本查不到
子类“继承”只是反射查找路径的延伸
子类 class 文件里并不会多出任何注解信息。所谓“继承”,是指调用以下方法时 JVM 自动向上遍历父类:
- getAnnotations():返回当前类 + 父类中所有被 @Inherited 修饰的运行时注解
- isAnnotationPresent(YourAnno.class):返回 true,哪怕子类没显式声明
- getAnnotation(YourAnno.class):能拿到父类上定义的注解实例
但 getDeclaredAnnotations() 始终只返回子类自己声明的注解,完全不查父类。
哪些情况完全不生效
@Inherited 的限制非常明确,以下场景一律无效:
- 注解标在方法、字段、参数或局部变量上——哪怕加了 @Inherited,子类重写方法也拿不到父方法的注解
- 类实现接口:接口上的 @Inherited 注解,实现类无法通过反射获取
- 接口之间extends:子接口不会继承父接口的任何注解
- 注解的 @Retention 是 SOURCE 或 CLASS:运行时反射不可见,继承性无从谈起
多层继承也支持,但仅限直接 extends 链
只要继承链是单根的(A → B → C),C 类调用 getAnnotation() 仍能拿到 A 类上被 @Inherited 修饰的注解。这说明 JVM 查找时会一直向上直到 Object,而不是只看直接父类。但要注意,这种查找只走 extends 路径,不走 implements 或组合关系。

