前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面试系列之-多态JVM的实现原理(JAVA基础)

面试系列之-多态JVM的实现原理(JAVA基础)

作者头像
用户4283147
发布2023-08-21 20:11:04
2630
发布2023-08-21 20:11:04
举报
文章被收录于专栏:对线JAVA面试

多态的机制及分类

一个对象变量可以指示多种实际类型的现象称为多态;允许不同类的对象对同一消息做出响应。方法的重载、类的覆盖(继承和实现)正体现了多态;

重载(overload 发生在一个类中,方法名必须相同,不同参数)就是编译时多态的一个例子,编译时多态在编译时就已经确定,运行时运行的时候调用的是确定的方法;

我们通常所说的多态指的都是运行时多态,也就是编译时不确定究竟调用哪个具体方法,一直延迟到运行时才能确定,这也是为什么有时候多态方法又被称为延迟方法的原因;

多态的实现原理

动态绑定和静态绑定

JVM在执行方法时,通常调用的指令有五个,分别是:

invokestatic:调用静态方法;

invokespecial:调用实例构造器方法、私有方法和父类方法;

invokevirtual:调用虚方法;

invokeinterface:调用接口方法,运行时确定具体实现;

invokedynamic:运行时动态解析所引用的方法,然后再执行,用于支持动态类型语言。

其中Invokestatic和invokespecial指令是用于静态绑定,invokevirtual 和 invokeinterface 用于动态绑定。

静态绑定指的是在编译期就能确定的,比如静态方法、构造器、私有方法和父类方法这4种方法在编译期就能解析引用确定的称为非虚方法,与之相对的就是虚方法,对象方法基本都为虚方法,例如某个类的drive(Car car),汽车子类实现类中的run()方法等;有个特例的是被final修饰的方法,由于不能被继承重写,所以是可以唯一确定的,是属于非虚方法,但却是使用invokevirtual指令调用的;

JVM底层多态实现过程

多态的实现过程,本质就是方法调用动态绑定的过程,通过栈帧的信息去找到被调用方法的具体实现,然后使用这个具体实现的直接引用完成方法调用;

invokevirtual指令在运行时解析大致分为以下几个步骤:

  1. 先从操作栈中找到对象的实际类型C;
  2. 找到C中与被调用方法签名相同的方法,如果有访问权限就返回这个方法的直接引用,如果没有访问权限就报错java.lang.IllegalAccessError ;
  3. 如果第2步找不到相符的方法,就去搜索C的父类,按照继承关系自下而上依次执行第2步的操作;
  4. 如果第3步找不到相符的方法,就报错java.lang.AbstractMethodError ;

可以看到,如果子类覆盖了父类的方法,则在多态调用中,动态绑定过程会首先确定实际类型是子类,从而先搜索到子类中的方法;

在程序运行时,动态绑定是一个非常高频的行为,JVM为了提高性能,避免反复搜索对应类型的绑定数据,会建立一个对应的虚方法表和接口方法表,使用对应的表索引来提高查询的性能;

以虚方法表为例,如果某个父类的方法在子类中没有被进行重写,那么此时子类和父类的虚方法表指向的地址是一致的,只有当出现子类重写了父类的方法时,才会出现子类的虚方法表与父类的虚方法表指向的地址不一样。因此如果子类没有重写父类的方法时,会随着父类的方法解析一同解析;

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-05-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 对线JAVA面试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 多态的机制及分类
  • 多态的实现原理
    • 动态绑定和静态绑定
    • JVM底层多态实现过程
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档