个人对Java 静态分派和动态分派的理解

# 首先Java 为什么会有这2中分派

        因为 . java文件在编译期间并不包括传统编过程中的连接环节,所以在生成的 .class文件中有关一切方法调用的信息都是用符号引用表示,并没有方法在实际运行是在内存中的入口地址。这一特性让Java有了强大的动态扩充能力,但也因此方法调用变得复杂,需要在类加载期间,甚至到运行期间才能确定目标方法的直接引用。(方法调用并不等于方法执行,方法调用阶段唯一的任务就是确定被调用方法的版本(即调用哪一个方法),暂时还不涉及方法内部的具体运行过程)。而根据确定调用那个方法的时期可以将方法调用分为静态分派和动态分派。

# 静态分派

        在编译期间,可以根据变量的静态类型确定方法执行版本的分派动作称作静态分派。典型的是方法的重载。

# 动态分派

          在编译期间确定不下来,只有在方法调用时,根据对象的实际类型确定方法执行版本的分派动作称作动态分派。 重写。

#Java虚拟机是如何根据实际类型来分派方法执行版本的呢?

            我们从invokevirtual指令的多态查找过程开始说起,invokevirtual指令的运行时解析过程大致分为以下几个步骤:
            1、找到操作数栈顶的第一个元素所指向的对象的实际类型,记作C。
            2、如果在类型C中找到与常量中的描述符和简单名称相符合的方法,然后进行访问权限验证,如果验证通过则返回这个       方法的直接引用,查找过程结束;如果验证不通过,则抛出java.lang.IllegalAccessError异常。
            3、否则未找到,就按照继承关系从下往上依次对类型C的各个父类进行第2步的搜索和验证过程。
            4、如果始终没有找到合适的方法,则跑出java.lang.AbstractMethodError异常。

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

#参考

Java静态分派与动态分派

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值