@Inherited仅使被其标记的类级注解可被子类继承,不适用于方法、字段或接口,且要求父类直接标注该注解;若未生效,需手动遍历继承链查找。
Java 里没有注解的“自动继承”这回事——它只对类上直接标注的注解生效,且仅限于被元注解标记过的注解,还不能穿透到方法、字段或接口实现上。
为什么 @Inherited 看起来“不工作”
这是最常踩的坑:
不是让子类“继承父类所有注解”,而是个非常窄的机制:当一个类 A 被某个带
的注解(比如自定义的
)标注时,它的子类 B 在调用
才可能拿到该注解——前提是
自身声明了
,且 A 是直接标注者。
父类方法上的注解,无论是否加
,子类重写后都拿不到(
查的是当前声明处)
接口上的注解永远不会被实现类继承(
对
声明无效)
如果父类没直接标注,而是通过其他注解(如 Spring 的
)间接获得,那更不会传递
如何真正让子类“看到”父类的注解
得自己写逻辑扫描继承链。核心是遍历
和
,逐层调用
。
只查类层级(不递归查接口),用
要支持接口,需额外处理
并递归其父接口(注意避免循环,比如
和
的关系)
Spring 的
就是这么干的,它比原生
多走了一层继承查找
示例片段:
@Inherited 的唯一有效使用场景
只有当你在定义自己的注解,并希望它能被子类“类级别继承”时,才需要加上
。否则,即使写了也毫无作用。
Eclipse导入Android或其他的JAVA项目的正确方法 WORD版
本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
下载
立即学习
“
Java免费学习笔记(深入)
”;
必须写在自定义注解定义上:
父类标注后,子类才能通过
拿到(前提是没被子类同名注解覆盖)
如果去掉
,哪怕父子类结构完全一样,子类也查不到
Spring Boot 的
、JUnit5 的
都用了这个机制,但它们内部还做了更多兼容处理
真正麻烦的从来不是加不加
,而是你得想清楚:到底要继承哪一层的注解?类?方法?参数?有没有元注解嵌套?要不要考虑桥接方法?这些都得手动处理,JVM 不会替你猜。
@Inherited@Inherited@Inherited@Inherited@MyAnnotationB.class.getAnnotation(MyAnnotation.class)@MyAnnotation@Inherited@InheritedgetDeclaredMethod(...).getAnnotation(...)@Inherited@interface@ServiceClass.getSuperclass()Class.getInterfaces()getAnnotation()Class> clazz = targetClass; while (clazz != null) { ... clazz = clazz.getSuperclass(); }clazz.getInterfaces()IterableCollectionAnnotationUtils.findAnnotation()getAnnotation()public static T findAnnotation(Class> clazz, Class annotationType) {
T ann = clazz.getAnnotation(annotationType);
if (ann != null) return ann;
Class> sup = clazz.getSuperclass();
if (sup != null) {
ann = findAnnotation(sup, annotationType);
if (ann != null) return ann;
}
return null;
} @Inherited@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyConfig { String value() default ""; }SubClass.class.getAnnotation(MyConfig.class)@Inherited@Configuration@TestInstance@Inherited