方法重载实现编译时多态,关键在于编译器根据方法名和参数列表(类型、个数、顺序)在编译期静态绑定调用目标,与运行时对象类型无关,返回值、修饰符等不影响重载判断。

方法重载实现静态多态,关键在于编译器在编译阶段就根据**方法名 + 参数列表(类型、个数、顺序)** 唯一确定调用目标,不依赖运行时对象的实际类型。
编译器靠参数签名做精确匹配
Java 编译器不会看变量声明类型或实际对象是谁,只看调用时传入的**实参类型和数量**。它在符号表中查找所有同名方法,逐个比对参数签名,选出最匹配的一个:
- 优先选“完全匹配”:实参类型与形参类型一致(如 int → int)
- 其次接受自动类型提升(如 byte → int)、装箱/拆箱(如 int → Integer)、可变参数(...)
- 如果出现二义性(比如两个重载都同样“合适”),编译直接报错
返回类型和访问修饰符不影响重载判断
重载只认方法名和参数列表,和返回值类型、throws 声明、static/final 修饰符都无关:
- 错误认知:“int add()” 和 “String add()” 是重载 → 实际是编译失败(重复方法名+相同签名)
- 正确示例:“void print(String s)” 和 “void print(Object o)” 是重载,因为 String 是 Object 的子类,但签名不同
静态分派发生在编译期,无运行时开销
编译后生成的字节码里,重载方法调用已固定为某条 invokestatic 或 invokespecial 指令,并携带明确的符号引用(类名、方法名、描述符)。JVM 加载时就能解析成直接地址,无需虚方法表(vtable)或运行时查表:
- 例如:
MathOperations.add(5, 3)编译后直接绑定到add(int, int)的符号引用 - 哪怕写
Object obj = new String(); obj.toString();,这里的toString()不是重载,而是重写——属于动态分派;而重载永远不涉及对象类型判断
注意:重载和重写的边界不能混淆
同一个类里的多个同名方法是重载;子类改写父类方法是重写。二者机制完全不同:
- 重载:同一类,参数不同,编译期定死,属于静态多态
- 重写:父子类间,签名相同,运行期按对象实际类型选方法,属于动态多态
- 一个方法既被重载又被重写是可能的(比如父类有
show(Object),子类重写它,又新增show(String)),但它们各自走各自的分派路径
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











