jvm中的动态分派

Posted 被罚站的树

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jvm中的动态分派相关的知识,希望对你有一定的参考价值。

动态分派与复写密不可分,因为java中存在向上转型,这样就涉及到方法的调用问题。先看一下示例代码

package com.dy.xidian;

class Test1 {

    public void say() {
        System.out.println("Test1");
    }
}
public class Test extends Test1 {

    public static void main(String[] args) {
        Test1 t = new Test();
        t.say();
    }

    public void say() {
        System.out.println("Test");
    }
}

代码中创建了一个Test()对象,然后将其向上转型为Test1类型,然后调用say()方法。那么问题来了,调用的say()是父类的方法还是子类的方法。先看一下字节码文件

在字节码文件中,我们可以观察到在main()方法中创建了Test文件,然后调用构造器(<init>)方法,紧接着调用Test1.say()方法。那么最后应该输出的是Test1,但是运行上面的代码会发现输出的是Test。出现这种原因和invokevirtual指令有关。

invokevirtual指令执行过程

  • 找到操作数栈顶的第一个元素所指向的对象的实际类型,记作C
  • 如果C中有对应的方法则直接返回该方法的直接引用(即C实现了改方法),否则按照继承关系从下往上依次对C的各个父类进行查找,如果没有查找到则抛出异常

所以上面代码中t是静态类型,编译时就可以确认,为Test1。而其对应的对象是实际类型,为Test。所以按照上面的步骤最后的结果输出的应该是Test。

 

以上是关于jvm中的动态分派的主要内容,如果未能解决你的问题,请参考以下文章

jvm原理(33)通过字节码分析Java方法的静态分派与动态分派机制(invokevirtual 指令)

jvm原理(33)通过字节码分析Java方法的静态分派与动态分派机制(invokevirtual 指令)

jvm原理(34)虚方法表与动态分派机制详解

jvm原理(34)虚方法表与动态分派机制详解

Jvm(66),方法调用----动态分派调用

[jvm解析系列][十二]分派,重载和重写,查看字节码带你深入了解分派的过程。