| 字节码 | 助记符 | 表示含义 |
| — | — | — |
| 0x04 | iconst_1 | 将int型1推送至栈顶 |
| 0xb7 | invokespecial | 调用超类构建方法, 实例初始化方法, 私有方法 |
| 0x1a | iload_0 | 将第一个int型本地变量推送至栈顶 |
| 0x10 | bipush | 将单字节的常量值(-128~127)推送至栈顶 |
至此我们不难明白 javap 的作用了,它主要就是找到字节码对应的的助记符然后再展示在我们面前的,我们简单看下上述的默认构造方法是如何根据字节码映射成助记符并最终呈现在我们面前的:
最左边的数字是 Code 区中每个字节的偏移量,这个是保存在 PC 的程序计数中的,比如如果当前指令指向 1,下一条就指向 4
另外大家不难发现,在源码中其实我们并没有定义默认构造函数,但在字节码中却生成了,而且你会发现我们在源码中定义了 private int a = 1;
但这个变量赋值的操作却是在构造方法中执行的(下文会分析到),这就是理解字节码的意义: 它可以反映 JVM 执行程序的真正逻辑 ,而源码只是表象,要深入分析还得看字节码!
接下来我们就来瞧一瞧构造方法对应的指令是如何执行的,首先我们来看一下在 JVM 中指令是怎么执行的。
-
首先 JVM 会为每个方法分配对应的局部变量表,可以认为它是一个数组,每个坑位(我们称为 slot)为方法中分配的变量,如果是实例方法,这些局部变量可以是 this, 方法参数,方法里分配的局部变量,这些局部变量的类型即我们熟知的 int,long 等八大基本,还有引用,返回地址,每个 slot 为 4 个字节,所以像 Long , Double 这种 8 个字节的要占用 2 个 slot, 如果这个方法为实例方法,则第一个 slot 为 this 指针, 如果是静态方法则没有 this 指针
-
分配好局部变量表后,方法里如果涉及到赋值,加减乘除等操作,那么这些指令的运算就需要依赖于操作数栈了,将这些指令对应的操作数通过压栈,弹栈来完成指令的执行
比如有 int i = 69
这样的指令,对应的字码节指令如下
0:bipush 69
2:istore_0
其在内存中的操作过程如下
可以看到主要分两步:第一步首先把 69 这个 int 值压栈,然后再弹栈,把 69 弹出放到局部变量表 i 对应的位置,istore_0 表示弹栈,将其从操作数栈中弹出整型数字存储到本地变量中,0 表示本地变量在局部变量表的第 0 个 slot
理解了上面这个操作,我们再来看一下默认构造函数对应的字节码指令是如何执行的
首先我们需要先来理解一下上面几个指令
-
aload_0:从局部变量表中加载第 0 个 slot 中的对象引用到操作数栈的栈顶,这里的 0 表示第 0 个位置,也就是 this
-
invokespecial:用来调用构造函数,但也可以用于调用同一个类中的 private 方法, 以及 可见的超类方法,在此例中表示调用父类的构造器(因为 #1 符号引用指向对应的 init 方法)
-
iconst_1:将 int 型 1推送至栈顶
-
putfield:它接受一个操作数,这个操作数引用的是运行时常量池里的一个字段,在这里这个字段是 a。赋给这个字段的值,以及包含这个字段的对象引用,在执行这条指令的时候,都会从操作数栈顶上 pop 出来。前面的 aload_0 指令已经把包含这个字段的对象(this)压到操作数栈上了,而后面的 iconst_1 又把 1 压到栈里。最后 putfield 指令会将这两个值从栈顶弹出。执行完的结果就是这个对象的 a 这个字段的值更新成了 1。
接下来我们来详细解释以上以上助记符代表的含义
- 第一条命令 aload_0,表示从局部变量表中加载第 0 个 slot 中的对象引用到操作数栈的栈顶,也就是将 this 加载到栈顶,如下
-
第二步 invokespecial #1,表示弹栈并且执行 #1 对应的方法,#1 代表的含义可以从旁边的解释(
# Method java/lang/Object." ":()V
)看出,即调用父类的初始化方法,这也印证了那句话: 子类初始化时会从初始化父类 -
之后的命令
aload_0
,iconst_1
,putfied #2
图解如下
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
最后
笔者已经把面试题和答案整理成了面试专题文档
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算**