缺少@override注解会导致“虚假重写”静默通过编译:方法看似重写成功,实则因签名不匹配(如参数类型错位、泛型擦除差异等)被当作新方法,多态调用时始终执行父类逻辑,bug隐蔽难查。

缺少 @Override 注解本身不会导致 bug,但会让本该失败的“虚假重写”悄然通过编译——方法看似重写了,实则只是同名新方法,多态调用时永远走父类逻辑,问题静默、难复现、难定位。
为什么没加 @Override 就会出事
Java 方法重写必须满足签名完全一致:方法名 + 参数类型(含顺序和具体泛型擦除后原始类型)+ 参数数量 + 返回类型兼容。只要其中一项不匹配,比如 List
快速识别是否真被重写了
- 在 IDE 中按住 Ctrl(Windows/Linux)或 Cmd(macOS),点击子类方法名,看能否跳转到父类/接口对应方法——跳不过去,基本就是假重写
- 检查父类方法是否为 private、static 或 final——这三类根本不可重写,加 @Override 会立刻报错,不加就埋雷
- 若重写的是接口 default 方法,确认子类确实 implements 了该接口,且 JDK 版本 ≥ 1.6(JDK 1.5 不支持 @Override 标记接口实现)
从开发习惯上杜绝这类问题
- 禁用手动敲 @Override + 手写方法体——这是高危操作,尤其参数多、泛型嵌套深时极易出错
- 一律用 IDE 自动生成:IntelliJ 右键 → Generate → Override Methods;Eclipse 右键 → Source → Override/Implement Methods
- 项目编译级别统一设为 JDK 1.8 或更高(避免旧版本对接口实现的支持差异)
- 在 CI 流程中启用静态检查工具(如 Checkstyle 或 ErrorProne),强制要求所有重写/实现方法带 @Override
修复已存在的隐式重载
不要只删掉错误方法再补 @Override。先做三件事:
- 查清父类或接口中原始方法的完整签名(包括泛型边界、通配符、throws 声明)
- 对比子类方法:参数类型是否用了具体实现类代替接口?返回值是否协变但越界?异常声明是否扩大?
- 改完后,在运行时用多态方式调用(如用父类/接口引用指向子类实例),确认执行的是子类逻辑而非父类默认行为










