@inherited仅对类级别注解生效且仅支持单层继承,需同时满足:注解自身用@inherited修饰、标注在父类上、保留策略为runtime、子类通过extends显式继承。

@Inherited 是 Java 中一个特殊的元注解,它**只对类的注解生效,且仅支持单层继承**——也就是说,它让子类自动“获得”父类上被 @Inherited 标记的注解,但这个过程不是真正的继承,而是一种运行时反射层面的“可见性透传”。
哪些注解可以被 @Inherited 传递?
必须同时满足两个条件:
- 该注解本身用
@Inherited修饰(即它是可继承的元注解) - 该注解是直接标注在类(class)上的,不能是方法、字段或参数上的注解
例如:
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "";
}
这时,如果 Parent 类加了 @MyAnnotation,它的子类 Child extends Parent 在反射中调用 Child.class.getAnnotation(MyAnnotation.class) 就能拿到该注解实例。
@Inherited 不会穿透多层,也不作用于接口和方法
常见误区:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 若
A extends B,B extends C,@MyAnnotation只标在C上,那么A无法通过@Inherited获取到它(不支持多级传递) - 接口上的
@Inherited注解不会被实现类继承(Java 规范明确排除接口) - 哪怕方法上用了
@Inherited注解,子类重写该方法时也不会自动带上——@Inherited对方法/字段注解完全无效
怎么验证 @Inherited 是否生效?
用反射检查即可:
@MyAnnotation("from parent")
class Parent {}
class Child extends Parent {}
// 运行时:
System.out.println(Child.class.getAnnotation(MyAnnotation.class));
// 输出:@MyAnnotation(value="from parent") —— 说明生效
但如果把 @MyAnnotation 改成标在方法上,或者父类没用 @Inherited 修饰该注解,则结果为 null。
替代方案:需要真正“继承”注解时怎么办?
因为 @Inherited 能力有限,实际开发中常需手动处理:
- 遍历类的整个继承链(
Class#getSuperclass()循环),逐个调用getAnnotation() - 结合 Spring 的
AnnotationUtils.findAnnotation(),它支持跨类继承查找(包括接口和桥接方法) - 自定义注解处理器,在编译期生成带继承信息的元数据(如 Lombok 风格)
总之,@Inherited 是一个轻量但有严格边界的机制,理解它的适用范围比盲目依赖更重要。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










