@inherited是修饰自定义注解的元注解,使该注解在类继承时自动传递给直接子类;需同时满足:注解自身声明@inherited、标注在类上、子类通过extends继承。

@Inherited 不是用来修饰 Java 类本身的,而是用来修饰**自定义注解类型**的元注解。它的作用很明确:让这个自定义注解在被用在某个类上时,能“自动传递”给该类的直接子类(仅限类继承,不适用于接口实现、方法或字段)。
必须满足的三个前提条件
只有同时满足以下三点,@Inherited 才会生效:
- 自定义注解本身必须显式声明 @Inherited 元注解
- 该自定义注解必须标注在类(class)上,不能标在方法、字段、参数等位置
- 子类必须通过 extends 继承父类,而不是 implements 接口,也不是组合或代理
@Inherited 不起作用的常见场景
这些情况哪怕加了 @Inherited 也完全无效:
- 把注解标在父类的方法上 —— 子类重写该方法后,不会继承该注解
- 父类实现了某个接口,而接口上有注解 —— 接口上的注解永远不会被实现类继承
- 子类用 @Override 重写了父类方法,但没在子类方法上再加注解 —— 方法级注解不传递
- 使用 Lombok 的 @Data 或 Spring 的 @Component 等框架注解 —— 它们自身未声明 @Inherited,所以不可继承
典型使用示例
下面是一个可运行的最小验证逻辑:
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Tracked {
String value() default "tracked";
}
@Tracked("base-config")
public class BaseService {}
public class UserService extends BaseService {} // 未显式标注 @Tracked
// 运行时可通过反射确认:
System.out.println(UserService.class.getAnnotation(Tracked.class).value());
// 输出:"base-config" —— 继承成功
适合用 @Inherited 的实际用途
它不是为日常业务编码设计的语法糖,而更适合框架层抽象:
- 统一配置基类:比如所有 Controller 基类标注 @ApiVersion("v1"),子类自动获得版本信息
- 测试框架支持:父测试类加 @TransactionalTest,所有子测试类默认开启事务回滚
- AOP 切面触发:基类加 @EnableLogging,子类方法自动被日志切面拦截(需配合自定义 AOP 逻辑)
- 组件注册简化:自定义 @BaseComponent 注解带 @Inherited,子类无需重复声明即可被容器扫描
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











