Java多态的核心是JVM通过虚方法表(vtable)实现动态绑定:每个类的vtable按固定顺序存储可重写实例方法的指针,父类方法优先排列,子类重写时同签名方法占据相同偏移量,JVM根据对象实际类型和偏移量快速定位方法入口。

Java 多态的核心是运行时动态决定调用哪个方法,而这个“决定权”落在 JVM 的虚方法表(Virtual Method Table,简称 vtable)上。它不是 Java 代码写的,而是 JVM 在类加载阶段自动生成并维护的数据结构,藏在方法区里。
虚方法表怎么组织的
每个类(包括抽象类,但不包括接口)在 JVM 中都有自己的 vtable,里面按固定顺序存放该类所有可被重写、且能参与多态的实例方法的直接引用:
- 先排父类定义的方法(按声明顺序),再排子类自己新增的方法;
- 如果子类重写了父类某个方法,那么子类 vtable 中对应位置的指针,会指向子类自己的实现,而不是父类的;
- 关键点:相同签名的方法,在父类和子类 vtable 中占据**同一偏移量(index)**,JVM 只需查对象实际类型的 vtable + 固定偏移,就能拿到正确方法入口。
多态调用时 JVM 怎么查表
当你写 animal.makeSound(),而 animal 实际是 Dog 对象时,JVM 执行过程如下:
- 通过对象头定位到它的实际类(Dog.class);
- 找到 Dog 类的 vtable;
- 根据 makeSound() 方法在 Animal 类 vtable 中的偏移量(比如第 3 位),直接去 Dog 的 vtable 第 3 位取方法指针;
- 跳转执行 Dog#makeSound。
整个过程不依赖方法名字符串匹配,也不遍历继承链,所以很快——这是动态绑定高效的关键。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
哪些方法不进虚方法表
vtable 只收录参与动态绑定的方法。以下情况不会出现在 vtable 中:
- static 方法:属于类,不依赖对象实例,直接由符号引用解析到具体地址;
- private 方法:无法被继承或重写,编译期就绑定(invokespecial);
- final 方法:虽可继承但禁止重写,JVM 可能内联或静态绑定;
- 构造方法:本质是特殊初始化逻辑,不参与多态调用。
接口方法为什么不一样
接口没有 vtable,而是用 itable(Interface Method Table)。因为一个类可能实现多个接口,且接口方法默认无实现,JVM 需额外查找类中真正提供该接口方法实现的具体位置。所以 invokeinterface 指令比 invokevirtual 开销略大,不过 JIT 编译器会在热点路径做优化,比如单实现类场景下直接转为 invokevirtual。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










