Java虚拟机对方法的调用

9 篇文章 0 订阅
3 篇文章 0 订阅

绑定过程

静态绑定与动态绑定
  • 静态绑定:
    指在解析阶段就能够直接识别到目标方法的情况。
    (重载可以看成静态绑定,因为对于重载方法的区分在编译阶段就已经完成,所以也可以认为Java虚拟机中不存在重载这一概念)

  • 动态绑定:
    指需要在运行过程中根据调用者的动态类型来识别目标方法的情况。
    (重写也可被称为动态绑定)

  • 在 class 文件中,编译器会用符号引用指代目标方法。在执行调用之类前,其符号引用会被解析成实际引用。

  • 对于静态绑定的方法调用来说,实际引用为直接指向目标方法的指针。

  • 对于动态绑定的方法调用而言,实际引用为一个方法表的索引。

符号引用解析成实际引用的过程

符号引用存储在 class 文件的常量池之中。根据目标方法是否为接口方法,这些引用可分为接口符号引用和非接口符号引用。
在执行使用了符号引用的字节码前,Java 虚拟机需要解析这些符号引用,并替换为实际引用。

  • 非接口符号引用:
    1)在 目标类中查找符合名字及描述符的方法。
    2)如果没有找到,在目标类的父类中继续搜索,直至 Object 类。
    3)如果没有找到,在目标类所直接实现或间接实现的接口中搜索,这一步搜索得到的目标方法必须是非私有、非静态的。并且,如果目标方法在间接实现的接口中,则需满足目标类与该接口之间没有其他符合条件的目标方法。如果有多个符合条件的目标方法,则任意返回其中一个。

  • 接口符号引用:
    1)在 I 中查找符合名字及描述符的方法。
    2)如果没有找到,在 Object 类中的公有实例方法中搜索。
    3)如果没有找到,则在 I 的超接口中搜索。这一步的搜索结果的要求与非接口符号引用步骤 3 的要求一致。

调用过程

对于静态绑定的方法调用而言,实际引用将指向具体的目标方法。对于动态绑定的方法调用而言,实际引用则是方法表的索引值(实际上并不仅是索引值)。

调用指令

  • invokestatic:用于调用静态方法。
  • invokespecial:用于调用私有实例方法、构造器,以及使用 super 关键字调用父类的实例方法或构造器,和所实现接口的默认方法。
  • invokevirtual:用于调用非私有实例方法。
  • invokeinterface:用于调用接口方法。
  • invokedynamic:用于调用动态方法。
非虚方法调用(静态绑定)

在 Java 虚拟机中,静态绑定包括用于调用静态方法的 invokestatic 指令,和用于调用构造器、私有实例方法以及超类非私有实例方法的 invokespecial 指令。如果虚方法调用指向一个标记为 final 的方法,那么 Java 虚拟机也可以静态绑定该虚方法调用的目标方法。

方法表
  • Java 虚拟机中采取了一种用空间换取时间的策略来实现动态绑定。它为每个类生成一张方法表,用以快速定位目标方法。
  • 方法表本质上是一个数组,每个数组元素指向一个当前类及其祖先类中非私有的实例方法。
  • 方法表满足两个特质:其一,子类方法表中包含父类方法表中的所有方法;其二,子类方法在方法表中的索引值,与它所重写的父类方法的索引值相同。
  • 在执行过程中,Java 虚拟机将获取调用者的实际类型,并在该实际类型的虚方法表中,根据索引值获得目标方法。这个过程便是动态绑定。
虚方法调用(动态绑定)

Java 里所有非私有实例方法调用都会被编译成 invokevirtual 指令,而接口方法调用都会被编译成 invokeinterface 指令。这两种指令,均属于 Java 虚拟机中的虚方法调用。

  • 虚方法调用包括 invokevirtual 指令和 invokeinterface 指令。如果这两种指令所声明的目标方法被标记为 final,那么 Java 虚拟机会采用静态绑定。否则,Java 虚拟机将采用动态绑定,在运行过程中根据调用者的动态类型,来决定具体的目标方法。
  • Java 虚拟机的动态绑定是通过方法表这一数据结构来实现的。方法表中每一个重写方法的索引值,与父类方法表中被重写的方法的索引值一致。
  • 在解析虚方法调用时,Java 虚拟机会纪录下所声明的目标方法的索引值,并且在运行过程中根据这个索引值查找具体的目标方法。
  • Java 虚拟机中的即时编译器会使用内联缓存来加速动态绑定。Java 虚拟机所采用的单态内联缓存将纪录调用者的动态类型,以及它所对应的目标方法。当碰到新的调用者时,如果其动态类型与缓存中的类型匹配,则直接调用缓存的目标方法。否则,Java 虚拟机将该内联缓存劣化为超多态内联缓存,在今后的执行过程中直接使用方法表进行动态绑定。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值