本质是误把重载当重写,因隐式类型转换导致签名不匹配;需用IDE跳转验证、检查访问修饰符、紧盯泛型与装箱细节,并强制使用@Override注解和IDE自动生成。

这个问题本质不是“重写出错”,而是**误把重载当重写**——方法签名因隐式类型转换(如自动装箱、类型提升、泛型擦除)发生偏移,导致子类方法没真正重写父类方法,反而成了同名新方法。多态调用时仍走父类逻辑,bug静默且难定位。
确认是不是真在重写,而不是假重载
先排除“看起来像重写,其实是新方法”的情况:
- 在IDE里按住 Ctrl(Windows/Linux)或 Cmd(macOS),点击子类方法名,看能否跳转到父类对应方法——跳不过去,基本就是签名不匹配
- 检查父类方法是否为 private、static 或 final:这三类根本不可重写,加 @Override 会立刻编译失败;不加就埋雷
- 若重写的是接口 default 方法,确认子类确实 implements 了该接口,且 JDK 版本 ≥ 1.8(JDK 1.5–1.7 不支持 @Override 标记接口实现)
盯紧参数类型细节,避免隐式转换干扰
Java 重写要求签名**完全一致**,而隐式转换常让开发者“以为一样,其实不同”:
-
自动装箱/拆箱陷阱:父类方法参数是
Integer,子类写成int→ 编译器视为两个不同参数类型,不构成重写 -
泛型擦除后失配:父类声明
void process(List<String> list),子类写成void process(ArrayList<String> list)→ 擦除后前者是List,后者是ArrayList,类型不等价 -
类型提升误导:父类方法是
void handle(long x),子类写成void handle(int x)→ 看似“更小”,实则签名不符,变成新方法
用 @Override 强制校验,别靠肉眼判断
@Override 不是装饰,是编译期契约检查工具:
立即学习“Java免费学习笔记(深入)”;
- 所有本意为重写的方法,必须显式加上 @Override 注解——不加,错误就静默通过
- 禁用手动敲写方法签名 + 手动加 @Override:极易漏掉泛型边界、通配符、throws 声明等细节
- 一律用 IDE 自动生成:IntelliJ 选 Generate → Override Methods,Eclipse 选 Source → Override/Implement Methods
- CI 流程中启用 ErrorProne 或 Checkstyle,配置规则强制所有重写方法带 @Override
修复已有“假重写”时的关键动作
不能只补个 @Override 就完事,得做三步验证:
- 查清父类/接口中原始方法的完整签名:包括泛型实际类型(非通配符)、throws 异常列表、返回值协变范围
- 逐项比对子类方法:参数是否用了具体实现类代替接口?返回值是否越界协变?异常声明是否扩大?
- 运行时验证多态行为:用父类或接口引用指向子类实例,再调用该方法,观察执行的是子类逻辑还是父类默认逻辑


















