通过字节码分析Java方法的静态分派与动态分派机制
在上一次【https://www.cnblogs.com/webor2006/p/9723289.html】中已经对Java方法的静态分派在字节码中的表现了,也就是方法重载其实是一种静态分派的体现,这次来分析一下与之对应的动态分派机制,其表现就是方法的重写多态机制,下面先来看下代码:
很显然是一个多态相关的代码,但结果会打印啥呢,看一下:
这个结果比上一节的要容易理解一些,是符合预期的,那从字节码角度如何来解释该程序的输出呢,下面详细来用jclasslib来分析一下它的字节码流程,如下:
上面是整个main方法对应字节码相关的信息,咱们一行行来分析:
其实也就是对应这句代码,生成Apple的一个实例:
看一下该助记符的官网解释:
其实就是调用了Apple的构造方法,以上三个助记符操作都是由new关键所发挥的作用,继续:
其中astore_1表示是存储在局部变量表序列号为1的变量中,那为1的局部变量是啥呢,到局部变量表中瞅一下就知道啦,如下:
也就是apple嘛,刚好跟源码对应:
以上就完成了源码的第一句代码,同样的对于第二次代码对应的助记符信息也类似,如下:
其中astore_2是保存在序列号为2的局部变量中,如下:
也就是给orange局部变量赋值了,接下来看下一句代码:
看下字节码:
看下官方解释:
而局部变量中序号为1的则就是apple如下:
接着调用Apple的test方法,但是从字节码中看到invokevirtual指令带的参数是调用的Fruit.test方法。。但是实际运行结果其实就是调用的Apple的test方法呢:
那不invokevirtual指令跟实际结果对不上了么,其实这是之后要重点学习的,这里先略过,先往下继续过流程,接着就是下一句代码了:
字节码类似的如下:
当然啦字节码中看到的是调用的Fruit.test()方法,跟结果调用的是Orange.test()结果是不符的,这个也先略过,继续看下一行代码:
对应字节码:
跟之前的操作类似,就不多说了,其中可以看到astore_1还是存在索引为1的局部变量apple,也就是引用给更新了,接下再往下看:
对应字节码如下:
最后整个方法返回:
到此,整个字节码完全分析完了,但是!!上面对于invokevirtual指令存有疑问,所以下面来解决它,先来看下这个指令的一个调用流程:
这其实是涉及到方法的动态分派,它涉及到一个很重要的概念:方法的接收者,也就是说该方法是由哪个对象所调用的,而invokevirtual字节码指令涉及到多态查找的流程,具体流程是:
1、首先要操作数栈的栈顶去寻找到栈顶的元素所指向对象的实际类型。对应于咱们的实际程序而言:
实际类型就是Apple。
2、如果在类型当中寻找到了与常量池中描述符名称相同的方法,如下:
,并且也具备一些方法的访问权限,也就是说去找看有没有实际类型的方法签名是public void test()的方法,很显然是能找到的,如下:
,那么就直接返回目标方法【对于我们程序也就是Apple.test()】的直接引用,整个过程就结束了;而如果找不到实际类型的该方法,则会从子类往父类的这种层次关系依次对各个父类重复同样的查找过程,一直到查到为止,查找到则就执行相印的方法,而如果一直找不到则就会抛出异常了。
比较方法重载(overload)与方法重写(overwrite),我们可以得到这样一个结论:方法重载是静态的,是编译期行为;方法重写是动态的,是运行期行为。而对于区分是不是方法重载和方法重写最重要的一个表现则是看方法的接收者,也就是方法的调用者是谁,像方法重载的调用者是同一个对像,如下:
因为test()方法本来就属于MyTest5类当中的。
而方法重写的调用者是不同的,如下:
也就是其调用的对象是子类的,而对于字节码是相同的符号引用而在运行期会被解析成不同的直接引用,这一点就是Java方法多态性极其重要的一个表现,如何理解?
而在运行期这两个类型会被解析Apple和Orange这两个直接引用。
通过字节码分析Java方法的静态分派与动态分派机制的更多相关文章
- 通过字节码分析java中的switch语句
在一次做题中遇到了switch的问题,由于对switch执行顺序的不了解,在这里简单的通过字节码的方式理解一下switch执行顺序(题目如下): public class Ag{ static pub ...
- 通过字节码分析Java异常处理机制
在上一次[https://www.cnblogs.com/webor2006/p/9691523.html]初步对异常表相关的概念进行了了解,先来回顾一下: 其源代码也贴一下: 下面来看一下jclas ...
- 透过字节码分析java基本类型数组的内存分配方式。
我们知道java中new方式创建的对象都是在堆中创建的,而局部变量对应的值存放在栈上.那么java中的int [] arr={1,2,3}是存放在什么地方的呢,int []arr = new int[ ...
- 透过字节码分析Java动态代理机制。
一.创建动态代理代码 1.创建接口 public interface Subject { void request(); } 2.创建接口实现类 public class RealSubject im ...
- 重读《深入理解Java虚拟机》五、虚拟机如何执行字节码?程序方法如何被执行?虚拟机执行引擎的工作机制
Class文件二进制字符流通过类加载器和虚拟机加载到内存(方法区)完成在内存上的布局和初始化后,虚拟机字节码执行引擎就可以执行相关代码实现程序所定义的功能.虚拟机执行引擎执行的对象是方法(均特指非本地 ...
- Java并发编程原理与实战八:产生线程安全性问题原因(javap字节码分析)
前面我们说到多线程带来的风险,其中一个很重要的就是安全性,因为其重要性因此,放到本章来进行讲解,那么线程安全性问题产生的原因,我们这节将从底层字节码来进行分析. 一.问题引出 先看一段代码 packa ...
- Java字节码分析
目录 Java字节码分析 查看字节码详细内容 javap 实例分析 Java字节码分析 对于源码的效率,但从源码来看有时无法分析出准确的结果,因为不同的编译器版本可能会将相同的源码编译成不同的字节码, ...
- Dalvik字节码的类型,方法与字段表示方法
Dalvik字节码有着自己的类型,方法与字段表示方法,这些方法与Dalvik虚拟机指令集一起组成了一条条的Dalvik汇编代码. 1.类型 Dalvik字节码只有两种类型,基本类型与引用类型.Dalv ...
- JVM-String比较-字节码分析
一道String字符串比较问题引发的字节码分析 public class a { public static void main(String[] args)throws Exception{ } p ...
随机推荐
- 一个websocket的demo(php server)
notice: 通过命令行执行php文件 如 php -q c:\path\server.php 通过本地web服务器访问 http://127.0.0.1/websocket/index.php即 ...
- 欧姆龙NX1P 输送马达功能块
一个简单的马达输送轨道功能块,需要的小伙伴可以参考下,个人能力有限,不足的地方还请包涵. 下载链接:https://pan.baidu.com/s/1V1gioE0boDpaUsR5cqQ5dg
- 图形学入门(3)——区域填充算法(region filling)
继续图形学之旅,我们已经解决了如何画线和画圆的问题,接下来要解决的是,如何往一个区域内填充颜色?对一个像素填充颜色只需调用SetPixel之类的函数就行了,所以这个问题其实就是:如何找到一个区域内的所 ...
- JAVA数据结构和算法 1-综述:数据结构和数据类型
数据结构:指数据在计算机内存空间中或者磁盘中的组织形式. 对于数据结构的操作:插入.删除.查找.迭代遍历.排序等: Java.util包中含有诸如向量(一个可扩充的数组).栈.哈希表等类型的数据结构, ...
- windows下进程与线程
windows下进程与线程 Windows是一个单用户多任务的操作系统,同一时间可有多个进程在执行.进程是应用程序的运行实例,可以理解为应用程序的一次动态执行:而线程是CPU调度的单位,是进程的一个执 ...
- Java面试题代码篇
1.统计字符串中的各种字符的个数并对其排序 package JavaMianSiTest; public class TongJIZiFu { public static void main(Stri ...
- EventLoop介绍
在Netty中使用EventLoop接口代表事件循环,EventLoop是从EventExecutor和ScheduledExecutorService扩展而来,所以可以讲任务直接交给EventLoo ...
- (十二)Sun公司的Jstl标签库详细介绍
JSP 本身提供的标签很少,不能满足我们日常开发需要,好在 Sun 公司自己提供了一套标签库: JSTL标签库快速入门(可点击) 目录 < c : out > 标签 < c : se ...
- 下载GDB调试工具peda
命令: 1.git clone https://github.com/longld/peda.git ~/peda 2.echo "source ~/peda/peda.py" & ...
- cliff
let me tell you,buddy. there's a faster gun. cming over yonder,when tomorrow comes.