JVM方法调用
当我们站在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方法调用的更多相关文章
- JVM方法调用过程
JVM方法调用过程 重载和重写 同一个类中,如果出现多个名称相同,并且参数类型相同的方法,将无法通过编译.因此,想要在同一个类中定义名字相同的方法,那么它们的参数类型必须不同.这种方法上的联系就是重载 ...
- Spring杂谈 | 从桥接方法到JVM方法调用
前言 之所以写这么一篇文章是因为在Spring中,经常会出现下面这种代码 // 判断是否是桥接方法,如果是的话就返回这个方法 BridgeMethodResolver.findBridgedMetho ...
- JVM 方法调用之静态分派
分派(Dispatch)可能是静态也可能是动态的,根据分派依据的宗量数可分为单分派和多分派.这两种分派方式的两两组合就构成了静态单分派,静态多分派,动态单分派,动态多分派这4种组合.本章讲静态分派. ...
- JVM 方法调用之解析
方法调用并不等同于方法执行,方法调用阶段唯一的任务就是确定被调用方法的版本(即调用哪一个方法),暂时还没有涉及到方法内部的具体运行过程.在程序运行时,进行方法调用是最普遍最频繁的操作,但Class文件 ...
- JVM 方法调用之动态分派
1. 动态分派 一个体现是重写(override).下面的代码,运行结果很明显. public class App { public static void main(String[] args) { ...
- JVM方法调用栈
摘自深入分析java web技术内幕
- 04 JVM是如何执行方法调用的(上)
重载和重写 重载:同一个类中定义名字相同的方法,但是参数类型或者参数个数必须不同. 重载的方法在编译过程中就可完成识别.具体到每一个方法的调用,Java 编译器会根据所传入参数的生命类型来选取重载方法 ...
- JVM(十二):方法调用
JVM(十二):方法调用 在 JVM(七):JVM内存结构 中,我们说到了方法执行在何种内存结构上执行:Java 方法活动在虚拟机栈中的栈帧上,栈帧的具体结构在内存结构中已经详细讲解过了,下面就让我们 ...
- 多态:JVM是如何进行方法调用的
在我们平时的工作学习中写java代码时,如果我们在同一个类中定义了两个方法名和参数类型都相同的方法时,编译器会直接报错给我们.还有在代码运行的时候,如果子类定义了一个与父类完全相同的方法的时候,父类的 ...
随机推荐
- POPTEST老李谈Debug和Release的区别(c#)
POPTEST老李谈Debug和Release的区别(c#) poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣 ...
- 老李推荐:第5章7节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 循环获取并执行事件 - runMonkeyCycles
老李推荐:第5章7节<MonkeyRunner源码剖析>Monkey原理分析-启动运行: 循环获取并执行事件 - runMonkeyCycles poptest是国内唯一一家培养测试开 ...
- php Redis常用命令
redis是一个很好的缓存工具,下面我们就来介绍一下他怎么使用 启动 Redis 服务src/redis-server或者src/redis-server redis.conf src/Redis-s ...
- 关于laravel框架的跨域请求/jsonp请求的理解
最近刚接触laravel框架,首先要写一个跨域的单点登录.被跨域的问题卡了两三天,主要是因为对跨域这快不了解,就在刚才有点茅塞顿开的感觉,我做一下大概整理,主要给一些刚接触摸不着头脑的看,哪里写得不对 ...
- Mysql Innodb体系结构
Innodb体系结构 Innodb存储引擎主要包括内存池以及后台线程. 内存池:多个内存块组成一个内存池,主要维护进程/线程的内部数据.缓存磁盘数据,修改文件前先修改内存.redo log 后台线程: ...
- MVC实现SSO
近来工作无事,想做个SSO, 之前做过一个项目用到SSO,自己也没有看明白是个什么东西.现在正好有时间,所以想研究下. 先是从网上看到了SSO的思路: 三个站点:SiteA,SiteB,SiteMai ...
- C#事物
执行ADO.NET事务包含四个步骤,分别为: ①调用SqlConnection对象的BeginTransaction()方法,(只调用这个方法前,要打开数据库连接,否则将会出现异常) 创建一个SqlT ...
- Spring事务执行过程
先说一下启动过程中的几个点: 加载配置文件: AbstractAutowireCapableBeanFactory.doCreateBean --> initializeBean --> ...
- [Oracle]LogMiner工具小结
(一)LogMiner工具的作用Logminer工具主要用来分析redo log和archive log文件.通过该工具,可以轻松获得Oracle redo log和archive log文件的具体内 ...
- python——杂货铺
三目运算: >>> 1 if 5>3 else 0 1 >>> 1 if 5<3 else 0 0 深浅拷贝: 一.数字和字符串 对于 数字 和 字符串 ...