父类引用调用重载方法不发生多态,而是静态分派,由编译期根据引用变量的声明类型及实参的数量、类型、顺序决定;子类新增的重载方法对父类引用不可见,因其属类内独立特性,不参与向上转型的可调用集合。

父类引用调用重载方法时,**不发生多态,而是静态分派(编译期决定)**,调用哪个重载版本,完全取决于**引用变量的声明类型(即静态类型)**,与实际创建的对象类型无关。
重载方法的分派发生在编译期
Java 编译器在编译阶段就根据方法调用处的:
- 引用变量的类型(不是对象真实类型)
- 实参的**数量、类型、顺序**
来匹配最合适的重载方法签名。一旦确定,字节码中就写死为对应方法的符号引用(如 invokevirtual Father.print(int)),运行时不会改变。
例如:
-
Father f = new Son();—— 静态类型是Father -
f.print(5);→ 编译器只看Father类中有没有接受int参数的print方法 - 即使
Son类额外定义了print(String)或print(double),只要Father没有print(int),这行代码就直接编译失败
为什么父类引用无法“看到”子类新增的重载方法
重载是**类内部的语法特性**,每个类独立维护自己的重载方法集。子类新增的重载方法(如 Son.print(String))对父类类型引用不可见,因为:
- 编译器只检查
Father类的直接定义 - 子类扩展的方法不属于父类的“接口契约”,不参与向上转型后的可调用集合
- 这和重写不同——重写是覆盖已有方法,而重载是增加新方法签名
对比:重载 vs 重写的分派时机
理解差异的关键在于分派机制:
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
立即学习“Java免费学习笔记(深入)”;
-
重载(Overload)→ 静态分派:由引用类型 + 实参类型共同决定,编译时绑定,
javac直接选好方法 - 重写(Override)→ 动态分派:由引用类型声明方法签名,但运行时根据对象实际类型查虚方法表(vtable),最终调用子类实现
所以:Father f = new Son(); f.func(); 若 func() 被重写,则执行 Son.func();若只是 Son 单独加了个 func(String) 重载,那 f.func("x") 根本通不过编译。
实际开发中的注意点
避免因混淆重载与重写导致的误判:
- 不要指望用父类引用去触发子类独有的重载方法——它根本“看不见”
- 若需按实际类型做不同逻辑,应使用重写 + 多态,或配合
instanceof+ 显式转型(但后者破坏封装) - 构造器支持重载,但构造器不能被继承,更不能被重写——这点也常被误用

















