@inherited是java中唯一控制注解继承性的元注解,仅对标注在类上的注解生效,且只适用于extends类继承,对接口实现、方法、字段、参数均无效。

@Inherited 是 Java 中唯一一个用于控制注解是否可被子类继承的元注解,但它**只对类上的注解生效,且仅适用于 extends 继承(即子类继承父类),对实现接口、方法重写、字段或参数上的注解均无效。
一、@Inherited 只作用于类级别注解
只有当注解本身被 @Inherited 修饰,并且该注解被直接标注在某个 类 上时,其子类才能通过 getAnnotations() 或 getAnnotation(Class) 获取到该注解。
- 接口上加了 @Inherited 注解 → 子类实现该接口时 不会继承 这个注解
- 方法、字段、参数上加了 @Inherited 注解 → 完全不起作用,Java 规范明确不支持
- 注解未用 @Inherited 修饰 → 即使标在父类上,子类也获取不到
二、接口无法通过 @Inherited 传递注解
Java 不支持“接口注解继承”。即使你定义了一个带 @Inherited 的注解并标注在接口上,实现该接口的类不会自动获得该注解。
例如:
@Inherited
@interface MyInterfaceAnno {}
@MyInterfaceAnno
interface MyService {
void doWork();
}
class MyServiceImpl implements MyService { // 此处不会拥有 @MyInterfaceAnno
public void doWork() {}
}
调用 MyServiceImpl.class.getAnnotation(MyInterfaceAnno.class) 返回 null。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
三、替代方案:运行时扫描接口注解
若需“模拟接口注解继承”,需手动检查类所实现的接口:
- 调用
clazz.getInterfaces()获取所有直接实现的接口 - 遍历每个接口,用
iface.getAnnotation(MyAnno.class)检查是否有目标注解 - 递归检查接口的父接口(
iface.getInterfaces())以支持多层继承
Spring 等框架常用此方式处理 @Transactional 在接口方法上的声明(虽然后续推荐写在实现类上)。
四、常见误区与验证建议
判断注解是否被继承,务必使用 Class.getAnnotation(),而非 isAnnotationPresent() —— 后者行为一致,但前者更直观;同时注意:
- 确保测试的是 运行时注解(
@Retention(RetentionPolicy.RUNTIME)) - 确认注解类上确实声明了
@Inherited - 避免混淆 “注解定义上的 @Inherited” 和 “被注解的目标是否支持继承”
最稳妥的方式是写个简单测试类,打印 SubClass.class.getAnnotation(YourAnno.class) 结果,眼见为实。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










