Java中父类引用调用重写方法采用动态绑定,实际执行方法取决于new出的对象真实类型而非引用声明类型;需满足继承、子类重写非static/private/final实例方法、父类引用指向子类对象三个条件。

Java 中父类引用调用重写方法时,走的是动态绑定(也叫运行时绑定、晚期绑定),核心在于:**实际执行哪个方法,取决于 new 出来的对象的真实类型(即堆中对象的运行时类型),而不是引用变量的声明类型。**
动态绑定发生的前提条件
要触发动态绑定,必须同时满足以下三点:
- 有继承关系(子类 extends 父类)
- 子类重写了父类的某个非 static、非 private、非 final 的实例方法
- 用父类类型引用指向子类对象(即“向上转型”,如 Parent p = new Child();)
调用过程:编译期检查 + 运行时分派
编译阶段只做语法和类型安全检查:
- 编译器确认父类中存在该方法(签名匹配),否则报错
- 不关心实际对象是谁,只认引用类型(Parent)有没有这个方法
运行阶段 JVM 才决定调用哪个版本:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
立即学习“Java免费学习笔记(深入)”;
- JVM 查看 p 实际指向的对象在堆中的真实类(Child)
- 在 Child 类的方法表(vtable)中查找该方法的最新实现
- 如果 Child 重写了,就执行 Child 的版本;否则沿继承链向上找,直到找到第一个实现
哪些方法不参与动态绑定?
以下情况看似“重写”,实则不走动态绑定,而是静态绑定(编译期确定):
- static 方法:属于类,不是对象,调用看引用类型(Parent.staticMethod() 永远调父类的)
- private 方法:不能被继承,子类里同名方法是全新方法,与父类无关
- final 方法:可继承但不可重写,自然没有多态选择
- 构造方法:不继承,也不重写,不存在动态绑定一说
一个典型例子
class Animal { void sound() { System.out.println("Animal makes sound"); } }
class Dog extends Animal { void sound() { System.out.println("Dog barks"); } }
class Cat extends Animal { void sound() { System.out.println("Cat meows"); } }
Animal a1 = new Dog();
Animal a2 = new Cat();
a1.sound(); // 输出 "Dog barks"
a2.sound(); // 输出 "Cat meows"
虽然 a1 和 a2 声明类型都是 Animal,但 JVM 在运行时分别识别出它们背后是 Dog 和 Cat 实例,所以调用各自重写的 sound()。

















