如何查看Java继承类虚函数表及run、swim方法的实际偏移量
Java虚方法表(vtable)的偏移逻辑
- 首先明确:你从class文件常量池中获取的是符号引用,和JVM运行时实际的vtable偏移没有直接的对应关系,字节码中
invokevirtual指令的操作数就是常量池的方法符号引用索引,并非偏移量。 - 主流JVM实现(比如HotSpot)的vtable设计逻辑和C++类似:为了保证多态调用的正确性,同一个方法签名在继承链的所有类的vtable中,偏移量是完全一致的。你示例中的
run、swim方法,在Father和Son的vtable中偏移确实相同。 - vtable的偏移不是直接基于方法名的字符串索引分配的,而是类加载的连接阶段完成方法解析后,按固定规则分配:
- 先完整复制父类的vtable结构,继承所有父类虚方法的偏移
- 子类重写的方法,直接覆盖vtable中对应偏移的条目
- 子类新增的虚方法,按顺序追加到vtable末尾,分配新的偏移
- 如果你需要获取运行时实际的vtable偏移,可以使用HotSpot自带的HSDB调试工具查看类的运行时元数据,BCEL只能读取静态的class文件结构,无法得到运行时的偏移信息。
补充说明:
invokevirtual第一次执行时,JVM会将常量池中的符号引用解析为对应的vtable偏移,之后的调用就可以直接使用偏移量快速寻址,和你看到的C++编译时就确定偏移的逻辑效果一致,但Java的偏移是类加载阶段确定的,不是编译时写死在字节码里的。
内容的提问来源于stack exchange,提问作者OrenIshShalom
相关产品推荐
相关产品推荐

