JVM04 Java虚拟机是如何执行方法调用的?

要调用就要先识别,Java和Java虚拟机是如何识别目标方法的呢?
在 Java 中,方法存在重载以及重写的概念,重载指的是方法名相同而参数类型不相同的方法之间的关系,重写指的是方法名相同并且参数类型也相同的方法之间的关系。
在Java 虚拟机中,除了方法名和参数类型之外,它还会考虑返回类型。

在 Java 虚拟机中,识别又分两种情况,静态绑定和动态绑定
静态绑定指的是在解析时便能够直接识别目标方法的情况,而动态绑定则指的是需要在运行过程中根据调用者的动态类型来识别目标方法的情况。由于 Java 编译器已经区分了重载的方法,因此可以认为 Java 虚拟机中不存在重载。

JVM提供了如下方法调用指令:
1、invokestatic: 调用静态方法。
2、invokespecial: 调用私有实例方法、构造器,以及使用super关键字调用父类的实例方法或构造器,和所有实现接口的默认方法。
3、invokevirtual: 调用虚方法即非私有的实例方法。
4、invokeinterface: 调用接口方法,在运行时再确定一个实现此接口的对象。
5、invokedynamic: 调用动态方法,在运行时动态解析出调用点限定符所引用的方法之后,调用该方法。

在 class 文件中,Java 编译器会用符号引用指代目标方法。在执行调用指令前,它所附带的符号引用需要被解析成实际引用。对于可以静态绑定的方法调用而言,实际引用为目标方法的指针。对于需要动态绑定的方法调用而言,实际引用为辅助动态绑定的信息。

虚方法调用包括invokevirtual指令和 invokeinterface指令。如果这两种指令所声明的目标方法被标记为 final,那么 Java 虚拟机会采用静态绑定。否则,Java 虚拟机将采用动态绑定,在运行过程中根据调用者的动态类型,来决定具体的目标方法。

Java 虚拟机的动态绑定是通过方法表这一数据结构来实现的。方法表中每一个重写方法的索引值,与父类方法表中被重写的方法的索引值一致。在解析虚方法调用时,Java 虚拟机会纪录下所声明的目标方法的索引值,并且在运行过程中根据这个索引值查找具体的目标方法。

Java 虚拟机中的即时编译器会使用内联缓存来加速动态绑定。Java 虚拟机所采用的单态内联缓存将纪录调用者的动态类型,以及它所对应的目标方法。

当碰到新的调用者时,如果其动态类型与缓存中的类型匹配,则直接调用缓存的目标方法。否则,Java 虚拟机将该内联缓存劣化为超多态内联缓存,在今后的执行过程中直接使用方法表进行动态绑定。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 第6章类文件结构 6.1 概述 6.2 无关性基石 6.3 Class类文件的结构 java虚拟机不和包括java...
    kennethan阅读 4,567评论 0 2
  • 此文为我在学习《深入理解Java虚拟机:JVM高级特性与最佳实践》时所做的笔记,把我认为是重点、面试时可能会被问到...
    CyanStone阅读 4,879评论 0 3
  • 第二部分 自动内存管理机制 第二章 java内存异常与内存溢出异常 运行数据区域 程序计数器:当前线程所执行的字节...
    小明oh阅读 4,930评论 0 2
  • 你头发湿了 写字楼博物馆图书馆 每一座城市不过失重蹈覆辙 玫瑰哪去了 满大街的倾世倾城 明媚给谁看 闪光灯早晚亮瞎...
    苏苏诺阅读 3,332评论 4 8
  • 走在马路上经常会想到一两歌词 而不记得歌名不记得歌手,看着静谧的星空,当然内心有很多疑问,眼看着要这些疑问要压倒在...
    飞猪2阅读 1,607评论 0 0

友情链接更多精彩内容