Java动态方法分派的运行机制及多态方法调用的运行时判定逻辑
Java动态方法分派的运行机制详解
Hey,很高兴能帮你理清这个Java多态背后的核心逻辑!咱们先从动态方法分派的运行机制说起,再结合你给的代码示例拆解细节:
一、动态方法分派的实际运行机制
动态方法分派是Java实现运行时多态的核心,整个流程可以拆解为三步:
- 编译时静态校验:编译器只关心变量的静态类型(也就是声明时的类型),会先检查这个静态类型中是否存在要调用的方法,如果不存在直接编译报错——这一步不涉及实际对象的类型,只是做合法性检查。
- 运行时获取动态类型:当程序运行到方法调用语句时,JVM会通过变量引用,找到它实际指向的对象,获取这个对象的动态类型(也就是
new关键字创建的类的类型)。 - 方法表快速定位方法:每个类在方法区中都维护着一张方法表(Method Table),里面存储了该类所有可调用方法的入口地址。如果子类重写了父类的方法,子类方法表中对应方法的入口会被替换成自己的实现。JVM拿到动态类型后,直接去它的方法表里查找目标方法的入口,然后执行对应的代码。
二、结合代码示例看Java如何确定调用的run()方法
咱们拿你提供的代码来具体拆解:
public class A{ public void run(){ System.out.println("This is A"); } } public class B extends A{ @Override public void run(){ System.out.println("This is B"); } } public class Dispatch{ public static void main(String args[]){ A var = new B(); var.run(); // prints : This is B } }
- 编译阶段:编译器看到
var的静态类型是A,检查A类中存在run()方法,所以编译通过。此时编译器只会记录“要调用静态类型A的run()方法”,但不会确定具体的实现版本。 - 运行阶段:JVM执行到
var.run()时,首先通过var这个引用找到它实际指向的对象——也就是new B()创建的实例。每个对象的对象头里都有一个指针,指向它所属类(B类)在方法区的元数据信息,而元数据中就包含B类的方法表。 - 方法表查找执行:由于
B类重写了A类的run()方法,B类的方法表中,run()方法的入口地址已经被替换为B自己的实现。JVM直接通过这个入口地址调用对应的方法,最终输出了This is B。
简单来说,就是编译看静态类型,运行看实际对象的动态类型,而方法表的存在让JVM能快速找到正确的方法实现,不用每次都遍历继承链~
内容的提问来源于stack exchange,提问作者ecdhe
相关产品推荐
相关产品推荐

