方法重写与重载本质不同:重写是子类覆盖父类同签名方法,需满足“两同两小一大”,发生在继承关系中;重载是同一类中同名异参的方法,仅参数列表不同。

方法重写(Override)和方法重载(Overload)根本不是一回事:前者是子类改父类的行为,发生在继承链上;后者是同一类里用同一个名字干不同的事,靠参数列表区分。
怎么判断是重写还是重载?看方法签名和所在位置
重写必须满足「两同两小一大」:方法名相同、参数列表完全相同;返回值类型≤父类(协变允许)、抛出异常≤父类;访问权限≥父类。它只可能出现在子类中,且父类方法不能是 private、final 或 static。
重载只要求「同名不同参」:同一类中,方法名一样,但参数个数、类型或顺序(类型不同时)至少有一项不同。返回值、访问修饰符、throws、是否 static 全都不影响重载判定。
- 常见错误:把
public void print(String s)和private void print(String s)当成重载——错,这是非法重复声明,编译直接报Duplicate method print(String) in type XXX - 另一个坑:写
void show(int a, String b)和void show(String b, int a)确实构成重载;但void show(int x, int y)和void show(int y, int x)不构成——参数类型顺序没变,只是变量名换了,JVM 视为同一签名
@Override 注解只对重写有效,对重载加了也没用还可能误导
@Override 是给编译器的明确信号:“我打算重写父类方法”。它会强制校验方法名、参数、返回值是否真能匹配到可重写的父类方法。拼错名、少一个参数、父类方法是 private,都会立刻报错。
立即学习“Java免费学习笔记(深入)”;
而重载方法加 @Override 会直接编译失败,因为编译器找不到被重写的父类方法。
- 实操建议:只要写了子类方法且意图是覆盖父类行为,无条件加上
@Override——哪怕父类方法来自Object(如toString()) - 反例:在工具类里写一堆
parse(String)、parse(int)、parse(Date),这些全是重载,加@Override就会触发Method does not override method from its superclass
运行时多态靠重写,编译时分发靠重载
重写是动态绑定:调用 Animal a = new Dog(); a.makeSound(); 时,JVM 到运行时才查 a 实际是 Dog 类型,去调 Dog.makeSound()。这就是多态的核心。
重载是静态绑定:编译器在编译阶段就根据变量声明类型和实参类型决定调哪个方法。比如 print(123) 调 print(int),print("abc") 调 print(String),跟对象实际类型无关。
- 性能提示:重载无运行时开销,纯编译期决策;重写有虚方法表查找成本,但现代 JVM 优化极好,不用刻意规避
- 典型陷阱:父类方法重载了多个版本,子类只重写其中一个——其他重载版本仍按父类逻辑执行,不会自动“继承重载”
最容易被忽略的是:重写要求参数列表「完全一致」,而重载要求参数列表「必须不同」——这两个「不同」的判定标准,全落在参数类型、个数、顺序(仅当类型不同时)上,和名字、返回值、修饰符统统无关。盯住参数列表,就抓住了本质。







