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 会在运行时依据对象的实际类型来确定调用哪个方法。具体步骤如下:
- 获取对象的实际类型:JVM 先获取引用变量所指向对象的实际类型。
- 查找方法表:接着,JVM 依据该实际类型找到对应的方法表。
- 确定方法引用:在方法表中查找被调用方法的签名,从而确定要调用的方法的引用。若子类重写了该方法,就会调用子类的实现;若未重写,则调用父类的实现。
示例解释
在 Main 类的 main 方法中,Parent obj = new Child(); 这行代码创建了一个 Child 类的对象,并将其赋值给 Parent 类型的引用变量 obj。当调用 obj.printMessage() 时:
- JVM 会获取
obj所指向对象的实际类型,即Child类。 - 然后找到
Child类的方法表。 - 在方法表中查找
printMessage方法的引用,由于Child类重写了该方法,所以方法表中对应的引用指向Child类的printMessage方法实现,最终调用的是子类的方法。
综上所述,JVM 借助方法表和动态绑定机制,在运行时依据对象的实际类型来确定调用哪个方法,从而实现了多态。
浙公网安备 33010602011771号