重载是编译期静态绑定,依据声明类型和实参类型/个数/顺序匹配方法;重写是运行期动态绑定,依据对象实际类型查vtable调用。

重载在编译期就定下调用哪个方法,重写则要等到运行时才确定执行谁的逻辑——这是两者最本质的差异。
重载:编译期静态绑定,看声明类型和实参字面量
编译器只根据方法名 + 实际传入参数的类型、个数、顺序来匹配,不关心对象真实类型。哪怕变量是父类引用,只要参数确定,就选定了具体方法。
- 例如:List
list = new ArrayList(); 调用 list.add("x"),编译器按 add(E) 解析,和多态无关 - 若同一类里还定义了 add(String),而你用 ArrayList 实例调用,编译器仍优先选 add(String)(因为实参是字面量字符串)
- 返回值类型不参与区分;仅靠返回值不同会报错:duplicate method
- 泛型擦除后签名相同(如 handle(List
) 和 handle(List) )也会编译失败
重写:运行期动态绑定,看对象实际类型
JVM 在运行时查虚方法表(vtable),根据对象堆内存中的真实类型跳转到对应实现。变量声明类型只是编译检查依据,不影响最终执行路径。
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- 例如:Animal a = new Dog(); a.speak(); 编译时确认 speak() 在 Animal 中存在,运行时才调 Dog::speak
- private、static、final 方法不能被重写;子类同名方法只是新定义或隐藏,不触发动态绑定
- 必须加 @Override 注解——它不是装饰,而是编译器帮你校验签名是否真能重写
- 协变返回允许子类返回更具体的类型(Animal → Dog),但不能更宽泛(Animal → Object 不行)
关键陷阱:别混淆“谁决定调用”和“谁被调用”
重载方法选哪个,由调用处的代码静态决定;重写方法执行谁的版本,由 new 出来的那个实例类型动态决定。二者叠加时尤其容易出错:
立即学习“Java免费学习笔记(深入)”;
- 父类引用调子类对象,再传参调用重载方法:先按父类声明类型找重载候选,再按实参匹配——跟子类无关
- 同一个类里既有重载又有继承重写:重载解析走编译期规则,重写分发走运行期规则,互不干扰但容易误判行为来源
- 静态方法可重载,也可被子类“同名定义”,但这不是重写,仍是编译期绑定,无多态性

















