美文网首页工作生活
java方法调用-动态分派

java方法调用-动态分派

作者: gzss | 来源:发表于2019-07-09 23:19 被阅读0次

前一篇文章聊了一下方法调用中的静态分派,这次我们聊下动态分派的过程,他和多态的另外一个重要体现-重写(override)有着很密切的关联。先看下如下代码:

运行结果:
man say hello

woman say hello

woman say hello

这个运行结果对于习惯了面向对象思维的java程序员来说相对比较简单。但是虚拟机是如何知道要调用哪个方法呢?

显然不能根据静态类型来决定,因为金泰类型同样都是human的两个变量man和woman在调用sayHello()方法时执行了不同的行为,并且变量man在两次调用中执行了不同的方法。导致这个现象的原因很明显,是这两个变量的实际类型不同,Java虚拟机是如何根据实际类型来分派方法执行版本呢,我们通过javap命令输出这段代码的字节码,参见下图:

0-15行的字节码是准备动作,作用是建立man和woman的内存空间、调用Man和Woman类的实例构造器,将这两个实例的引用存放在第1、2个局部变量表Slot之中,这个动作也对应代码中的这两句:
Human man = new Man();

Human woman = new Woman();

接下来16-21句是关键部分,16、20分别把刚刚建立的两个对象的引用压倒栈顶,这两个对象时将要执行sayHello()方法的所有者,称为接收者;17和21句是方法的调用指令,这两条调用指令从字节码角度来看,无论指令还是参数完全一样,但是这两句指令最终执行的目标方法并不相同。原因就需要从invokevirtual指令的多态查找过程开始说起,invokevirtual指令的运行时解析过程大致分为以下几个步骤:

1、找到操作数栈顶的第一个元素所指向的对象实际类型,记做C。

2、如果在类型C中找到与常量中的描述符合简单名称都相符的方法,则进行访问权限校验,如果通过则返回这个方法的直接引用,查找过程结束;如果不通过,则返回java.lang.IllegalAccessError异常。

3、否则,按照继承关系从下往上依次对C的各个父类进行第2步的搜索和验证操作。

4、如果始终没有找到合适的方法,则抛出java.lang.AbstractMethodError异常

由于invokevirtual指令执行的第一步就是在运行期确定接收者的实际类型,所以两次调用中invokevirtual指令吧常量池中的类方法符号引用解析到了不同的直接引用上,这个过程就是java语言中方法重写的本质。我们把这种在运行期根据实际类型确定方法执行版本的分派过程称为动态分派。

相关文章

  • java方法调用-动态分派

    前一篇文章聊了一下方法调用中的静态分派,这次我们聊下动态分派的过程,他和多态的另外一个重要体现-重写(overri...

  • java虚拟机之方法调用(下)——单分派与多分派

    前言 上一篇讲解了静态分派和动态分派,还不清楚的同学可以先看看:java虚拟机之方法调用(上)——静态分派与动态分...

  • Java方法分派

    静态分派 - 方法重载分派编译期确定根据调用者的声明类型和方法参数类型分派 动态分派 - 方法重写分派运行时确定根...

  • Java虚拟机——方法调用

    方法调用要确定被调用的方法版本,分为三种,解析调用、静态分派和动态分派。 解析调用 解析调用时调用目标在程序代码写...

  • 重载选择(静态分派),解析调用与动态分派(多态)的特性研究

    根据周志明《深入理解java虚拟机》所述,国内把重载方法的选择过程叫做静态分派,除此之外是解析调用和动态分派。个人...

  • Java静态分派、动态分派、双重分派

    动态分派和静态分派机制是java多态的实现原理。 静态分派(方法重载) 静态分派机制最典型的代码: 这段代码执行完...

  • java方法调用-静态分派

    在聊静态分派前,我们先看一段代码,想象一下程序的输出结果是什么。后面我们将围绕这个类的方法来重载(overload...

  • java方法调用-单分派与多分派

    根据分派基于多少种宗量(方法的接收者与方法的参数统称为方法的宗量),可以将分派划分为单分派和多分派两种。单分派是根...

  • 多态->分派

    摘抄深入理解java虚拟机目标 分派包括: 静态分派与动态分派两种类型, 静态分派的使用场景为重载, 动态分派使用...

  • Swift中的VTable简述

    在Swift中方法的调度分为静态方法直接调用与动态分派两种方式 静态方法静态方法表示其为不可变的,为了提高调用的效...

网友评论

    本文标题:java方法调用-动态分派

    本文链接:https://www.haomeiwen.com/subject/vsrocctx.html