0

0

从JVM角度看Java多态的调用指令

畫卷琴夢

畫卷琴夢

发布时间:2026-01-21 15:39:39

|

409人浏览过

|

来源于php中文网

原创

invokevirtual 是 Java 多态的运行时执行指令,根据对象实际类型查虚方法表(vtable)动态分派;编译期仅做符号解析,不决定具体实现。

从jvm角度看java多态的调用指令

invokevirtual 是 Java 多态的实际执行指令

Java 编译器不会为 override 方法生成特殊字节码,而是统一使用 invokevirtual 指令。它在运行时根据对象实际类型(而非引用类型)查虚方法表(vtable),再跳转到具体实现。这就是“动态绑定”的 JVM 层实现。

常见误解是“编译期决定调用哪个方法”,其实编译期只做符号解析:确认方法签名是否合法、是否存在可访问的声明,但不锁定具体实现类。真正分派发生在 invokevirtual 执行时。

  • invokevirtual 要求目标方法是非私有、非静态、非 final 的实例方法(否则可能被内联或走其他指令)
  • 如果子类覆盖了父类方法,JVM 会在子类的 vtable 中覆写该方法槽位,指向子类版本的字节码入口
  • 接口方法调用用的是 invokeinterface,原理类似但查的是 itable,开销略高

为什么 final 方法不走 invokevirtual?

标记为 final 的实例方法无法被覆盖,JVM 可以在 JIT 编译阶段直接内联或使用 invokespecial 调用——后者不查 vtable,只按编译期类型静态定位方法地址。

这带来两个实际影响:

立即学习Java免费学习笔记(深入)”;

  • 性能上更优:省去虚方法查表和多态分派开销
  • 行为上更确定:哪怕通过反射修改类结构,final 方法也不会被动态替换(JVM 层面禁止)
  • 注意:private 方法也用 invokespecial,但它是编译期静态绑定,连运行时多态语义都不具备

invokespecial 和 invokevirtual 的关键区别

二者都用于调用实例方法,但语义完全不同:invokespecial 强制走“当前类声明的方法”,无视子类覆盖;而 invokevirtual 必须走运行时实际类型的实现。

典型使用场景包括:

靠岸学术
靠岸学术

一款集翻译,阅读,文献管理于一体的英文文献阅读器

下载
  • 构造器调用(<init></init> 方法永远用 invokespecial
  • 显式调用父类被覆盖的方法(如 super.toString()
  • private 方法调用

如果你在字节码里看到 invokespecial 却期望多态行为,大概率是误用了 super 或方法被错误设为 final / private

看懂字节码里的多态调用链

javap -v 查看编译后字节码,重点关注方法调用指令和常量池中的符号引用。多态的关键不在源码写法,而在指令选择和类加载后的 vtable 布局。

一个简单验证方式:

class A { void m() { System.out.println("A"); } }
class B extends A { void m() { System.out.println("B"); } }
public class Test {
    public static void main(String[] args) {
        A a = new B();
        a.m(); // 这行编译为 invokevirtual #3,#3 指向 A.m() 的符号引用
    }
}

虽然符号引用指向 A.m(),但运行时 a 实际是 B 实例,JVM 查 B 的 vtable 发现该槽已被替换成 B.m() 的入口地址。

容易被忽略的是:vtable 在类加载的准备/初始化阶段构建,且一旦建立,除非触发类卸载(极少见),否则不会随运行时对象变化而重排。所以多态不是“每次调用都重新查找”,而是查一次表 + 直接跳转。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

WorkBuddy
WorkBuddy

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
java基础知识汇总
java基础知识汇总

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

1568

2023.10.24

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

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

27

2025.11.27

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

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

27

2025.11.27

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

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

27

2025.11.27

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1958

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

658

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2401

2025.12.29

java接口相关教程
java接口相关教程

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

47

2026.01.19

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.4万人学习

C# 教程
C# 教程

共94课时 | 11.3万人学习

Java 教程
Java 教程

共578课时 | 81.9万人学习

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

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