
@Override 注解的保留策略为 SOURCE,编译后即被丢弃,因此无法在运行时通过反射(如 isAnnotationPresent())检测其存在。
`@override` 注解的保留策略为 `source`,编译后即被丢弃,因此无法在运行时通过反射(如 `isannotationpresent()`)检测其存在。
在 Java 中,@Override 是一个仅在源码阶段生效的元注解(@Retention(RetentionPolicy.SOURCE)),其设计目的纯粹是供编译器进行语义检查——确保被标注的方法确实重写了父类或接口中的方法。一旦代码通过 javac 编译完成,该注解信息将完全从字节码中移除,不会出现在 .class 文件的 RuntimeVisibleAnnotations 或 RuntimeInvisibleAnnotations 属性中。
因此,以下两种常见反射方式均会返回 false,即使源码中明确写了 @Override:
Method method = SomeClass.class.getDeclaredMethod("toString");
System.out.println(method.isAnnotationPresent(Override.class)); // false
// 使用 Spring 的 MergedAnnotations(需 spring-core 5.2+)
boolean hasOverride = MergedAnnotations.from(method).isPresent(Override.class);
System.out.println(hasOverride); // false
✅ 正确理解与替代方案:
- ✅ 不要尝试在运行时“检测”
@Override—— 这在技术上不可行,也违背其设计初衷; - ✅ 若需验证重写关系,应通过
Method.getDeclaringClass()与继承链分析:public static boolean isOverridden(Method method) { Class> declaringClass = method.getDeclaringClass(); Class> superclass = declaringClass.getSuperclass(); if (superclass != null) { try { superclass.getDeclaredMethod(method.getName(), method.getParameterTypes()); return true; // 在父类中找到同名同签名方法 → 极大概率是重写 } catch (NoSuchMethodException ignored) {} } // 检查接口(含默认方法) for (Class> intf : declaringClass.getInterfaces()) { try { intf.getDeclaredMethod(method.getName(), method.getParameterTypes()); return true; } catch (NoSuchMethodException ignored) {} } return false; } - ⚠️ 注意:此逻辑仅作近似判断,不能 100% 等价于编译器的
@Override检查(例如未处理桥接方法、泛型擦除、协变返回类型等复杂场景),但对多数调试或工具类需求已足够可靠。
? 总结:@Override 是编译期契约,不是运行时元数据。若你的工具链需要感知“重写意图”,请转向静态分析(如使用 JavaParser、Eclipse JDT 或编译器插件),而非依赖反射。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











