jvm层面是如何实现多态的,比如我调用了父类的对象jvm是如何知道我调用的是子类的方法

在 JVM 层面,多态主要通过动态绑定(Dynamic Binding)和方法表(Method Table)机制来实现,下面详细介绍 JVM 是如何确定调用子类方法的。

多态的基础:继承与重写

在 Java 里,多态依赖于继承和方法重写。你可以创建一个父类类型的引用变量,不过它能指向子类的对象。当调用该引用变量的方法时,若此方法在子类中被重写,就会调用子类的实现。示例代码如下:

class Parent {
    public void printMessage() {
        System.out.println("This is the parent class.");
    }
}

class Child extends Parent {
    @Override
    public void printMessage() {
        System.out.println("This is the child class.");
    }
}

public class Main {
    public static void main(String[] args) {
        Parent obj = new Child();
        obj.printMessage(); // 调用子类的方法
    }
}

JVM 实现多态的机制

1. 方法表(Method Table)

  • 定义:每个类在 JVM 里都有一个方法表,它是一个数组,其中存储了该类所有实例方法的引用。方法表中的每个条目对应着一个方法,这些条目按方法的签名进行索引。
  • 继承与重写的体现:子类的方法表会继承父类的方法表,要是子类重写了父类的某个方法,那么子类方法表中对应条目的引用就会指向子类的方法实现;若子类没有重写该方法,就会沿用父类方法表中的引用。

2. 动态绑定(Dynamic Binding)

  • 静态类型与实际类型:在 Java 中,变量有静态类型和实际类型。静态类型是变量声明时的类型,而实际类型是变量所指向对象的真实类型。在上述代码中,obj 的静态类型是 Parent,但实际类型是 Child
  • 调用过程:当通过父类引用调用一个实例方法时,JVM 会在运行时依据对象的实际类型来确定调用哪个方法。具体步骤如下:
    1. 获取对象的实际类型:JVM 先获取引用变量所指向对象的实际类型。
    2. 查找方法表:接着,JVM 依据该实际类型找到对应的方法表。
    3. 确定方法引用:在方法表中查找被调用方法的签名,从而确定要调用的方法的引用。若子类重写了该方法,就会调用子类的实现;若未重写,则调用父类的实现。

示例解释

Main 类的 main 方法中,Parent obj = new Child(); 这行代码创建了一个 Child 类的对象,并将其赋值给 Parent 类型的引用变量 obj。当调用 obj.printMessage() 时:

  • JVM 会获取 obj 所指向对象的实际类型,即 Child 类。
  • 然后找到 Child 类的方法表。
  • 在方法表中查找 printMessage 方法的引用,由于 Child 类重写了该方法,所以方法表中对应的引用指向 Child 类的 printMessage 方法实现,最终调用的是子类的方法。

综上所述,JVM 借助方法表和动态绑定机制,在运行时依据对象的实际类型来确定调用哪个方法,从而实现了多态。

posted on 2025-05-02 23:38  斜月三星一太阳  阅读(69)  评论(0)    收藏  举报