java多态底层基于动态绑定,jvm通过虚方法表(vtable)在运行时根据对象实际类型查找并调用对应方法;static、private、final方法及构造器采用静态绑定,字段访问不参与多态。

Java 多态的底层原理,核心在于动态绑定——也就是运行时才决定调用哪个具体方法。它不是靠编译器猜,而是 JVM 在程序跑起来后,根据对象真实的类型,从一张叫“虚方法表(vtable)”的结构里快速查到对应方法的地址,然后跳过去执行。
虚方法表是动态绑定的基础设施
JVM 在类加载阶段,就为每个类生成一张虚方法表。这张表本质是一个数组,按方法在源码中声明的顺序,存着该类所有可被重写、非静态、非 final、非 private 的实例方法的字节码入口地址。
- 父类的 vtable 包含父类自己定义的这些方法地址
- 子类的 vtable 会先复制父类的条目,再把被重写的方法替换成子类自己的实现地址
- 如果子类没重写某个方法,vtable 里仍保留父类方法的地址
方法调用时发生了什么
当你写 animal.speak(),而 animal 是 Animal 类型但实际指向 Dog 对象时:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 编译期只检查
Animal类有没有speak()方法,有就通过,生成invokevirtual指令 - 运行期 JVM 看到这个指令,不看变量声明类型(Animal),而是顺着对象内存地址,找到它真实所属的类(Dog)
- 再查
Dog类的 vtable,定位到speak()对应的槽位,直接跳转到 Dog 版本的字节码执行
哪些方法不走动态绑定
不是所有方法都参与这套机制。以下情况由编译期直接锁定目标,属于静态绑定:
-
static 方法:只看引用变量的声明类型,比如
Parent p = new Child(); p.method()调的是Parent.method - private 方法:隐式 final,仅本类可见,无法重写,编译器直接绑定到当前类
- final 实例方法:禁止重写,JVM 可优化为静态绑定
- 构造方法:不支持重写,也不属于多态范畴
属性访问不参与多态
多态只对方法调用生效。访问字段(如 obj.name)永远看引用的编译时类型:
- 即使
Student s = new Student(),但用Person p = s去访问p.money,取的是Person类定义的money - 子类独有的字段,用父类引用根本无法访问,编译直接报错
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










