当我们站在JVM实现的角度去看方法调用的时候,我们自然会想到一种分类:

1、编译代码的时候就知道是哪个方法,永远不会产生歧义,例如静态方法,private方法,构造方法,super方法。

2、运行时才能确定是哪个方法,这也正是多态的实现原理。

对于第一种方法的调用,有2个字节码指令:invokestatic,invokespecial

invokestatic:调用static方法(不需要通过类的实例就可以调用),这很好理解。静态方法属于整个类型,就一份,没有歧义。

invokespecial:调用private方法、构造方法,super方法。private方法是不会被子类继承下去的,所以不会有歧义,这和通过super去调用父类的方法是一个道理。

对于第二种方法的调用,有2个字节码指令:invokevirtual,invokeinterface

invokevirtual:这部分的方法运用了方法表,对方法表中的方法的直接引用表现为偏移量(1、2、3.....),我认为这就像是数据库中的索引。在子类的方法表中,从父类继承下来的方法总是在方法表的前面,而子类重写的方法在方法表中指向自己的实现,于是多态得以实现。当调用方法时,JVM通过具体的对象引用找到实际类,进而找到正确的方法。

invokeinterface:和invokevirtual的实现一样,但是针对接口的方法的实现,在各个实现类的方法表中,不能通过偏移量来快速查找,因为各个方法表中的偏移量可能不相同,只能全表扫描,所以速度会慢很多。

tips:A a = new B(),这里的A叫做静态类型,B叫做实际类型,A针对第一种调用,B针对第二种调用。

                  参考《深入理解Java虚拟机》

JVM方法调用的更多相关文章

  1. JVM方法调用过程

    JVM方法调用过程 重载和重写 同一个类中,如果出现多个名称相同,并且参数类型相同的方法,将无法通过编译.因此,想要在同一个类中定义名字相同的方法,那么它们的参数类型必须不同.这种方法上的联系就是重载 ...

  2. Spring杂谈 | 从桥接方法到JVM方法调用

    前言 之所以写这么一篇文章是因为在Spring中,经常会出现下面这种代码 // 判断是否是桥接方法,如果是的话就返回这个方法 BridgeMethodResolver.findBridgedMetho ...

  3. JVM 方法调用之静态分派

    分派(Dispatch)可能是静态也可能是动态的,根据分派依据的宗量数可分为单分派和多分派.这两种分派方式的两两组合就构成了静态单分派,静态多分派,动态单分派,动态多分派这4种组合.本章讲静态分派. ...

  4. JVM 方法调用之解析

    方法调用并不等同于方法执行,方法调用阶段唯一的任务就是确定被调用方法的版本(即调用哪一个方法),暂时还没有涉及到方法内部的具体运行过程.在程序运行时,进行方法调用是最普遍最频繁的操作,但Class文件 ...

  5. JVM 方法调用之动态分派

    1. 动态分派 一个体现是重写(override).下面的代码,运行结果很明显. public class App { public static void main(String[] args) { ...

  6. JVM方法调用栈

    摘自深入分析java web技术内幕

  7. 04 JVM是如何执行方法调用的(上)

    重载和重写 重载:同一个类中定义名字相同的方法,但是参数类型或者参数个数必须不同. 重载的方法在编译过程中就可完成识别.具体到每一个方法的调用,Java 编译器会根据所传入参数的生命类型来选取重载方法 ...

  8. JVM(十二):方法调用

    JVM(十二):方法调用 在 JVM(七):JVM内存结构 中,我们说到了方法执行在何种内存结构上执行:Java 方法活动在虚拟机栈中的栈帧上,栈帧的具体结构在内存结构中已经详细讲解过了,下面就让我们 ...

  9. 多态:JVM是如何进行方法调用的

    在我们平时的工作学习中写java代码时,如果我们在同一个类中定义了两个方法名和参数类型都相同的方法时,编译器会直接报错给我们.还有在代码运行的时候,如果子类定义了一个与父类完全相同的方法的时候,父类的 ...

随机推荐

  1. ng自定义一个过滤器

    ng允许我们自定义指令 下面来我们自己来定义一个过滤指令:filter,返回一个函数的形式 filter(name,callback(){//name:过滤器的名字,callback:匿名函数 ret ...

  2. 【转】flash air中读取本地文件的三种方法

    actionscript中读取本地文件操作有两种代码如下 1.使用File和FileStream两个类,FileStream负责读取数据的所以操作:(同步操作) var stream:FileStre ...

  3. 什么是测试开发工程师-google的解释

    什么是测试开发工程师-google的解释 “ 软件测试开发工程师[SET or Software Engineer in Test],和软件开发工程师一样是开发工程师,主要负责软件的可测试性.他们参与 ...

  4. 老李分享:接电话之uiautomator 2

    case解释 首先要了解进入uiwatcher方法中的机制,是在你某个控件找不到的情况下会进入.但是你得保证进入以后处理完来电界面以后,这条case得保证正确,那么说明回来以后这个控件要能找到.刚开始 ...

  5. Unix文件 I/O(不带缓冲区的)上

    简介 Unix系统大多数文件i/o只需要:open.read.write.lseek.close这几个函数.但是某些时候我们也需要fcntl.ioctl.sync等函数配合使用.这些函数都是不带缓冲区 ...

  6. Javascript删除数组中指定值的元素

    Array.prototype.remove = function(index){ if(isNaN(index) || index > this.length){return false;} ...

  7. .NET中数据访问方式(一):LINQ

    语言集成查询(Language-Integrated Query),简称LINQ,.NET中的LINQ体系如下图所示:   在编程语言层次,LINQ对于不同的数据源提供了相同的查询语法,方便了程序员操 ...

  8. 1136: 零起点学算法43——多组测试数据输出I

    1136: 零起点学算法43--多组测试数据输出I Time Limit: 1 Sec  Memory Limit: 128 MB   64bit IO Format: %lldSubmitted: ...

  9. ECP系统J2EE架构开发平台

    一 体系结构 ECP平台是一个基于J2EE架构设计的大型分布式企业协同管理平台,通过采用成熟的J2EE的多层企业架构体系,充分保证了系统的健壮性.开放性和扩展性.可选择部署于多种系统环境,满足不同类型 ...

  10. 2017年陕西省网络空间安全技术大赛——种棵树吧——Writeup

    2017年陕西省网络空间安全技术大赛——种棵树吧——Writeup 下载下来的zip解压得到两个jpg图片,在Kali中使用binwalk查看文件类型如下图: 有两个发现: 1111.jpg 隐藏了一 ...