聊聊JVM虚方法表和方法调用
作者:小牛呼噜噜 | https://xiaoniuhululu.com计算机内功、源码解析、科技故事、项目实战、面试八股等更多硬核文章,首发于公众号「小牛呼噜噜」
大家好,我是呼噜噜,好久没更新文章了,今天我们来填个坑,在之前的一篇文章深挖⾯向对象编程三⼤特性 --封装、继承、多态中我们遗留了一个问题:当父类引用指向子类对象时,JVM是如何知晓调用的是哪个子类的方法?
动态绑定和静态绑定我们下文还是用之前文章的例子,简单修改一下:
(资料图片仅供参考)
public class ClassTest { static class Animal { public void eat(){ System.out.println("动物吃饭!"); } public void work(){ System.out.println("动物可以帮助人类干活!"); } } static class Cat extends Animal { public void eat() { System.out.println("吃鱼"); } public void sleep() { System.out.println("猫会睡懒觉"); } } static class Dog extends Animal { public void eat() { System.out.println("吃骨头"); } } public static void main(String[] args) throws Exception { Animal cat=new Cat(); cat.eat(); cat.work(); //cat.sleep();//此处编译会报错。 }}
当父类引用指向子类对象时,也就是Animal cat=new Cat();
这个也叫做向上转型,重写式多态。
这种多态其实是通过动态绑定(dynamic binding)技术来实现,是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。也就是说,只有程序运行起来,你才知道调用的是哪个子类的方法。这种多态可通过函数的重写以及向上转型来实现。
与动态绑定相对应的就是静态绑定,指的是在JVM解析时便能够直接识别目标方法的情况。网上有些文章说,重载和静态绑定直接挂钩,这其实是不完全正确的,笔者举个极端的例子:当某个类中的重载方法被它的子类重写时,那它其实通过了动态绑定。
重载指的是方法名相同而参数类型不相同的方法之间的关系,重写指的是方法名相同并且参数类型也相同的方法之间的关系
需要注意的是:本文一直在说程序在运行期间发生的事,而方法调用在静态阶段(编译)以声明的静态类型为准,不管符号引用指向的是哪个实例对象。编译成字节码再进入JVM,进行类加载
我们回到刚刚的例子上:cat.eat();
这句的结果打印:吃鱼。程序这块调用我们子类Cat定义的方法,而不是父类的同名方法。cat.work();
这句的结果打印:动物可以帮助人类干活!我们上面Cat类没有定义work方法,但是却使用了父类的方法,这是不是很神奇。其实此处调的是父类的同名方法cat.sleep();
这句 编译器会提示 编译报错。表明:当我们当子类的对象作为父类的引用使用时,只能访问子类中和父类中都有的方法,而无法去访问子类中特有的方法。虽然向上转型是安全的。但是缺点是:一旦向上转型,子类会丢失的子类的扩展方法,其实就是 子类中原本特有的方法就不能再被调用了。所以cat.sleep()
这句会编译报错。
由此我们可以发现规律:当发生向上转型,去调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。如果子类没有同名方法,会再次去调父类中的该方法。这种根据对象的实际类型而不是声明类型来选择并调用方法的过程也叫做动态分派(Dynamic Dispatch)但如果直接这样去查找,会发生循环查找,效率较低,为了解决这个问题,虚方法表就出现了,也就是动态绑定的底层原理。
虚方法表与虚方法JVM 虚方法表(Virtual Method Table),也称为vtable,是动态调度用来依次调用虚方法的一种表结构,是一种特殊的索引表。
面向对象编程,会频繁地触发动态分派,如果每次动态分配的过程都要重新在类的方法 元数据中搜索合适的目标的方法,就可能影响到执行效率,所以JVM选择了 用空间换取时间的策略来实现动态绑定,为每个类生成一张虚方法表,然后直接通过虚方法表,使用索引来代替循环查找,快速定位目标方法。
在类加载器与双亲委派机制一网打尽一文中,我们知道 类的生命周期一般有如下图有7个阶段,其中阶段1-5为类加载过程,验证、准备、解析统称为连接虚方法表会在类加载的连接阶段被创建,JVM扫描类的方法信息,识别哪些是虚方法,并在虚方法表中储存其对应的 方法的相关信息以及这些方法在虚拟机内存方法区中的入口地址。这入口地址就是该方法的虚拟方法表的索引,JVM可以通过这个索引地址找到对应的方法。也就是说,每个类的对象都会拥有自己的虚方法表
那什么是虚方法和非虚方法?
非虚方法:如果方法在编译期就确定了具体的调用版本,则这个版本在运行时是不可变的,这样的方法称为非虚方法静态方法。比如私有方法,final 方法,实例构造器,父类方法都是非虚方法,除了这些以外都是虚方法
当Java中发生向上转型,呈现重写式多态时,如果子类没有重写父类方法,子类并不会复制一份父类的方法到自己的虚方法表中,就会去父类的虚方法表中查找 目标方法
。
子类的重写的方法和父类中的同名方法在字节码层面方法索引通常来说是一样的,如果在子类找到方法eat()
,其索引是0
,发现不是要调用的方法后,而是要调用父类的eat()
,就会直接去父类方法索引为0
的地方查找,这样能进一步提高查找效率。
从JVM底层来了解方法调用,我们还需知晓 在JVM中和方法调用有关的指令有5种:
invokeinterface:调用接口中的方法,实际上是在运行期决定的,决定到底调用实现该接口的哪个对象的特定方法。invokestatic:调用静态方法。invokespecial: 调用私有实例方法、构造器方法;使用super关键词调用父类的实例方法、构造器;调用所实现接口的default方法invokevirtual:调用非私有实例方法,也就是虚方法,运行期动态查找的过程。invokedynamic: 调用动态方法,JDK7新加入的一个虚拟机指令,相比于之前的四条指令,他们的分派逻辑都是固化在JVM内部,而invokedynamic则用于处理新的方法分派:它允许应用级别的代码来确定执行哪一个方法调用,只有在调用要执行的时候,才会进行这种判断,从而达到动态语言的支持。(Invoke dynamic method)我们javap来反编译上文例子生成的class文件ClassTest.class:
public com.zj.ideaprojects.demo.test4.ClassTest(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."":()V 4: return LineNumberTable: line 3: 0 public static void main(java.lang.String[]) throws java.lang.Exception; descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=2, args_size=1 0: new #2 // class com/zj/ideaprojects/demo/test4/ClassTest$Cat 3: dup 4: invokespecial #3 // Method com/zj/ideaprojects/demo/test4/ClassTest$Cat."":()V 7: astore_1 8: aload_1 9: invokevirtual #4 // Method com/zj/ideaprojects/demo/test4/ClassTest$Animal.eat:()V 12: aload_1 13: invokevirtual #5 // Method com/zj/ideaprojects/demo/test4/ClassTest$Animal.work:()V 16: return LineNumberTable: line 30: 0 line 31: 8 line 32: 12 line 34: 16 Exceptions: throws java.lang.Exception
我们可以发现: Java 中所有非私有实例方法调用都会被编译成 invokevirtual指令
,而接口方法调用都会被编译成 invokeinterface 指令
。这两种指令,均属于Java 虚拟机中的虚方法调用,会进行函数的动态绑定。
invokevirtual指令
在执行时,首先在运行期确定方法接收者的实际类型,并不是把常量池中方法的符号引用(在这里相当于常量池里的方法信息)解析到直接引用上就结束了,而是接着根据方法接收者的实际类型来选择方法版本,这个过程也就是Java多态的本质。
针对于invokeinterface指令来说,虚拟机会建立一个叫做接口方法表的数据结构(interface method table,简称itable),和虚方法表类似。
另外,当我们了解invokespecial指令,invokestatic指令
时,可以知晓,父类引用在调用静态方法,私有方法或是接口default方法是不会发生多态,而是直接调用声明类型的方法。
在Java 8中Lambda表达式和默认方法时,底层会生成和使用invokedynamic,很有意思的一个指令,本文就不详细介绍该指令了,以后有机会再讲讲。
小结小结一下,本文主要讲解了方法调用在Java虚拟机的实现方式,以及虚方法表在 JVM 方法调用中充当了一个中介的角色,使得 JVM 能够实现多态性和动态分派。最后带大家了解一下JVM常见的方法调用的指令,Java可不仅仅只有CRUD哦
参考资料:
https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5.2
《Java虚拟机规范》
《深入理解Java虚拟机:JVM高级特性与最佳实践第3版》
全文完,感谢您的阅读,如果我的文章对你有所帮助的话,还请点个免费的赞,你的支持会激励我输出更高质量的文章,感谢!
原文镜像:聊聊JVM虚方法表和方法调用
计算机内功、源码解析、科技故事、项目实战、面试八股等更多硬核文章,首发于公众号「小牛呼噜噜」,我们下期再见!
标签:
-
2022-05-23 16:13:32
上海奉贤等区开展常态化防疫压力测试 有序开放公交、公园、公共服务场所、公共街区商区<
本报上海5月21日电 (记者刘士安、曹玲娟)上海正在奉贤等区开展常态化防疫压力测试。在21日召开的上海市疫情防控工作新闻发布会上,奉
-
2022-05-23 16:13:32
“抗疫 宅家云课堂”,吸引沪上老同志观看50万人次<
由上海市委老干部局主办,上海市老干部大学、市科技助老服务中心承办的“抗疫 宅家云课堂”系列直播讲座自4月12日启动以来,深受老同
-
2022-05-23 16:13:32
“代跑腿”买药、开通绿色通道 丰台为管控区居民提供便捷医疗服务<
“真是太感谢了,解决了我的燃眉之急!”家住假日万恒社区的杨女士对前来送药的居委会工作人员说。 自5月17日6时起,丰台区对青塔街...
-
2022-05-23 16:13:32
上海嘉定:儿童计划免疫接种全部恢复,实行预约制<
在5月22日召开的上海市新冠肺炎疫情防控新闻发布会上,嘉定区副区长王浩介绍,从4月28日开始,嘉定在防范区逐步有序恢复老年人疫苗接种
-
2022-05-23 16:13:32
乡村振兴看新疆 | 种下红樱桃 结出“致富果”<
央广网阿图什5月22日消息(记者 罗成 通讯员 杨林)乡村振兴靠产业,产业发展靠特色。新疆阿图什市阿扎克镇麦依村积极引导农民因地制
-
2023-07-04 09:30:50
聊聊JVM虚方法表和方法调用
>作者:小牛呼噜噜|[https: xiaoniuhululu com](https: xiaoniuhulul
-
2023-07-04 09:05:39
当前看点!艾多美轻享代餐粉九宫格自拍来了,加倍营养,轻盈有料
艾多美轻享代餐粉加倍营养,轻盈有料椰香牛油果风味科学营养配比全面营
-
2023-07-04 08:27:28
纽约金价3日微涨
纽约商品交易所黄金期货市场交投最活跃的8月黄金期价3日比前一交易日上
-
2023-07-04 07:57:40
苏州火车站候车室男子热晕了? 医院表示患者体温超40℃有其他疾病
苏州火车站候车室男子热晕了?医院表示患者体温超40℃有其他疾病---楚
-
2023-07-04 06:54:43
浙江省湖州市2023-06-23 23:04发布暴雨蓝色预警_焦点快播
一、浙江省湖州市天气预报1、湖州市气象台2023年06月23日23时02分将暴
-
2023-07-04 06:33:24
世界快消息!新型铁电材料可变身机器人“肌肉”
科技日报北京7月3日电(记者刘霞)美国科学家领导的一个国际研究小组表
-
2023-07-04 05:35:10
世界速读:美国“毒”病难除丨毒品泛滥愈演愈烈 美国禁毒为何失败?
50多年前,时任美国总统尼克松曾对毒品“宣战”,而美国的“毒”病反而
-
2023-07-04 03:12:10
7月3日基金净值:华夏上证科创板50成份ETF最新净值1.0539,涨0.3%
7月3日,华夏上证科创板50成份ETF最新单位净值为1 0539元,累计净值为0
-
2023-07-04 01:08:33
热讯:键盘进水按键错乱是主板坏了吗_键盘进水按键错乱
1、如果是防水键盘晾干应该就会回复,但如果恢复不了,除非键盘很有价
-
2023-07-03 23:08:22
乾隆年间一文钱等于多少人民币(一文钱等于多少人民币)
来为大家解答以上的问题。乾隆年间一文钱等于多少人民币,一文钱等于多
-
2023-07-03 21:53:21
三七互娱累计回购约496万股,公司遭立案面临投资者索赔
雷达财经雷助吧出品文|冯秀语编|深海7月3日晚间,三七互娱公告称,公司
-
2023-07-03 21:14:17
杨幂生发液 杨幂露背了 基本情况讲解 环球热议
大家好,今日关于【杨幂生发液杨幂露背了】迅速上了的热搜榜,受到全网
-
2023-07-03 20:56:30
阳历3月5日是什么星座_3月5日是什么星座
1、3月5日出生的人是双鱼座。2、双鱼座(Pisces)的出生日期为2月19日
-
2023-07-03 20:09:33
潘西是什么菜_潘西是什么意思-环球新动态
1、为哈利波特系列丛书中一位女生的名字,出生于1980年左右1991-1998年
-
2023-07-03 19:38:27
药明康德: 关于2019年限制性股票与股票期权激励计划首次授予股票期权2023年第二季度自主行权结果暨股份变动公告|天天快看
药明康德:关于2019年限制性股票与股票期权激励计划首次授予股票期权202
-
2023-07-03 19:00:57
互动| 罗博特科:公司已经完成单体GW铜电镀设备的制造与出货
罗博特科互动回复:公司已经完成单体GW铜电镀设备的制造与出货,鉴于与
-
2023-07-03 18:05:26
涉案资金1900余万元 重庆彭水警方破获一起非法集资诈骗案
近日,重庆市公安局经侦总队公布2022年破获的一起非法集资典型案例。该
-
2023-07-03 17:40:54
7月3日山东地区醋酸行情观望运行
企业产能生产情况兖矿国泰120万吨 年日产3000吨华鲁恒升60万吨 年日产1
-
2023-07-03 17:31:54
【全球新视野】洛阳偃师区检察院走访慰问生活困难党员、老党员
大河网讯火红七月,浓浓深情。6月30日上午,洛阳市偃师区人民检察院党
-
2023-07-03 17:02:02
焦点滚动:踢开IPO大门,Keep投资价值几何?
另从渠道和品牌来看,Keep本身是中国最大的线上健身平台,拥有垂直、精
-
2023-07-03 16:34:03
全国首个!北京理工大学发布“元宇宙”录取通知书
北京理工大学2023年录取通知书。北京理工大学供图中国青年报客户端讯(
-
2023-07-03 16:23:37
AI投资或步入“新阶段” 机构锚定确定性调仓换股
截至6月30日,人工智能指数近两周回调超4%,浪潮信息股价回撤近14%,华
-
2023-07-03 15:42:34
全国农民技能大赛吸引300名选手角逐-报资讯
新华社济南7月3日电3日,来自全国31个省(区、市)和新疆生产建设兵团
-
2023-07-03 15:23:04
机械行业市场调研 中国林业机械行业市场容量及未来发展方向|天天速讯
机械行业市场到底怎么样? 在“十三五”时期,林业机械投入科研经费180
-
2023-07-03 14:51:19
专访视障高考考生马奕菲:她把自己活成了光|全球微速讯
面对面|专访视障高考考生马奕菲:她把自己活成了光央视新闻客户端记者
-
2023-07-03 14:32:17
2023中国最北极昼马拉松开跑 中外3000余选手参赛
2023中国北极·漠河极昼马拉松在漠河市北极村鸣枪开跑。 邵天李 摄中
-
2023-07-03 13:53:59
白油膏商品报价动态(2023-07-03)_天天速读
交易商品牌 产地交货地最新报价白油膏 橡胶软化剂济南鑫厚商贸有限公
-
2023-07-03 13:09:54
援助缅北受害者家属:坚守噩梦中的爱与希望
陈欣和陈童是互助群里最早主动联系我的人,也是和我交流最多的两位受骗
-
2023-07-03 12:47:00
上海张江“20张江一”共回售8亿元 拟全部转售 世界观点
“20张江一”发行总额8亿元,期限为3+2年期,当前票面利率为3 67%,202
-
2023-07-03 12:10:25
每日热闻!威马汽车及沈晖被限制消费 威马汽车集团成老赖
该公司还因此案被列为失信被执行人(老赖)。
-
嘉峪关合资公司律师事务所收费标准是多少|短讯
2022-12-21 03:48:36 -
南亚国家减贫与发展研修班第二期在重庆开班-当前热讯
2022-12-20 16:09:19 -
国网信通:目前公司暂未开展电力数据的定价和数据交易等相关业务
2022-12-20 11:01:59 -
泉峰汽车: 中国国际金融股份有限公司关于南京泉峰汽车精密技术股份有限公司调整可转换公司债券募投项目募集资金投入方式的核查意见 即时
2022-12-19 22:11:41 -
陆金贷(小额应急)逾期16年延迟还款会影响征信吗
2022-12-19 15:49:26 -
天天热点!工作人员宣布杨颖取消今晚直播,连续取消多个行程的她被曝已感染新冠
2022-12-19 09:53:36 -
多西对“推特文件门”的回应,藏着Web3满满的愿景
2022-12-19 00:13:43