You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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
    }
}
  1. 编译阶段:编译器看到var的静态类型是A,检查A类中存在run()方法,所以编译通过。此时编译器只会记录“要调用静态类型A的run()方法”,但不会确定具体的实现版本。
  2. 运行阶段:JVM执行到var.run()时,首先通过var这个引用找到它实际指向的对象——也就是new B()创建的实例。每个对象的对象头里都有一个指针,指向它所属类(B类)在方法区的元数据信息,而元数据中就包含B类的方法表。
  3. 方法表查找执行:由于B类重写了A类的run()方法,B类的方法表中,run()方法的入口地址已经被替换为B自己的实现。JVM直接通过这个入口地址调用对应的方法,最终输出了This is B。

简单来说,就是编译看静态类型,运行看实际对象的动态类型,而方法表的存在让JVM能快速找到正确的方法实现,不用每次都遍历继承链~

内容的提问来源于stack exchange,提问作者ecdhe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:38:22