0

0

JVM中多态的底层原理是什么_虚方法表(vtable)与接口方法表(itable)解析

P粉602998670

P粉602998670

发布时间:2026-03-17 12:08:01

|

716人浏览过

|

来源于php中文网

原创

多态调用查vtable或itable:非接口引用走vtable,接口引用走itable;二者均在类加载链接阶段静态构建,final/private/static方法不入表。

jvm中多态的底层原理是什么_虚方法表(vtable)与接口方法表(itable)解析

多态调用到底查的是哪个表?vtable 还是 itable

Java 多态的动态分派,不是靠“猜”对象类型,而是靠两张硬编码在类元数据里的跳转表:子类继承链用 vtable(虚方法表),实现接口则额外维护一张 itable(接口方法表)。JVM 在解析 invokevirtual 指令时,先看调用目标是否是接口引用——是,走 itable;否则一律走 vtable

  • 父类引用指向子类实例,比如 Animal a = new Dog(); a.speak(); → 查 Dogvtable,索引位置和 Animal.speak() 在其 vtable 中的偏移一致
  • 接口引用调用,比如 Runnable r = () -> {}; r.run(); → JVM 先在 r 实际类型(如 LambdaForm$T123)的 itable 中定位 Runnable.run 对应的实现入口
  • vtable 是每个类一份,按继承顺序“摊平”所有可被重写的方法(含从 Object 继承的),空缺位填 abstract 或父类实现;itable 是接口维度组织,每个实现类为每个它实现的接口单独存一张映射

为什么 final 方法、private 方法、static 方法不进 vtable

因为它们压根不参与动态绑定——编译期就锁死了目标字节码符号,JVM 直接生成 invokespecialinvokestatic 指令,绕过所有查找表。你哪怕在子类里“重写”了一个 private 方法,那也只是个同名新方法,跟父类的毫无关系。

  • final void close() 被调用时,字节码是 invokespecial,不查表,也不管运行时对象是谁
  • private String helper() 即使子类也定义了同签名方法,父类内部调用它永远只绑定到父类版本
  • static 方法本质是“类级别函数”,调用目标由字节码里的符号引用决定,与对象实例无关,自然不进任何实例方法表

虚方法表不是运行时生成的,是类加载时静态构建的

vtableitable 都在类加载的“链接”阶段(具体是验证后的准备阶段)由 JVM 构建完成,不是每次 new 对象时临时算的。这意味着:表结构在类第一次被主动使用前就固定了,后续所有该类实例共享同一份表指针。

皮卡智能
皮卡智能

AI驱动高效视觉设计平台

下载
  • 子类新增重写方法,会覆盖父类 vtable 中对应槽位;若新增非重写方法(如新 public 方法),则追加到表尾
  • 如果子类没重写某个父类方法,vtable 里那个槽位直接存父类方法的直接引用(可能跨多个继承层级)
  • 接口默认方法(default)会被加入实现类的 vtable,但接口静态方法(static)不会——它只进接口自己的常量池,不进任何 itable

容易被忽略的坑:接口多实现时 itable 的冲突与桥接

当一个类同时实现多个接口,且这些接口定义了相同签名的 default 方法,编译器会强制要求你显式 override 并选择调用哪一个——否则连编译都过不去。但更隐蔽的坑在于:JVM 在构建 itable 时,对每个接口独立填充,不合并;而某些 default 方法在字节码层面会生成桥接方法(bridge method),导致 itable 条目指向的其实是合成的桥接器,而非你写的原始方法。

  • 比如 InterfaceAInterfaceB 都有 default void log(String s),你实现类里写了 @Override public void log(String s) { ... },JVM 会在 itable 中为两个接口分别填入这个方法的引用,但实际执行时走的是你写的那个实现
  • 泛型接口的 default 方法(如 <T> T get())可能触发桥接,itable 条目指向的是编译器生成的 get()Ljava/lang/Object;,而不是你源码里带泛型的那个
  • javap -v 看 class 文件,搜索 interfaces:itable: 区域,能直接看到每张表的条目和对应方法引用——这是调试多态行为最硬核的手段
虚方法表和接口方法表不是黑盒机制,它们是 JVM 类文件格式中明确定义的数据结构;真正容易出问题的地方,往往不在“有没有表”,而在“表里填了什么”——尤其是涉及 default 方法、泛型桥接、以及类加载时机时,表内容和你的直觉可能差了一层编译器。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1091

2023.08.02

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1570

2023.10.24

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

27

2025.11.27

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

27

2025.11.27

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

27

2025.11.27

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

188

2023.11.23

java中void的含义
java中void的含义

本专题整合了Java中void的相关内容,阅读专题下面的文章了解更多详细内容。

135

2025.11.27

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

550

2023.12.01

c++ 字符处理
c++ 字符处理

本专题整合了c++字符处理教程、字符串处理函数相关内容,阅读专题下面的文章了解更多详细内容。

0

2026.03.17

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号