首先建议先看一下基于前面的字节码知识:Java字节码的一段旅行经历——提升硬实力1
在日常的项目开发中,经常遇到a++、++a、a--之类,下面我们开始从字节码的视角来分析a++。
java代码如下:
/*
从字节码角度分析 a++ 相关题目
*/
public class T03_ByteAnalyseAPlusPlus {
public static void main(String[] args) {
int a = 10;
int b = a++ + ++a + a--;
System.out.println(a);
System.out.println(b);
}
}
使用javap -v xxx.class 来查看类文件全部指令信息:javap -v T03_ByteAnalyseAPlusPlus,如下:
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=3, args_size=1
0: bipush 10
2: istore_1
3: iload_1
4: iinc 1, 1
7: iinc 1, 1
10: iload_1
11: iadd
12: iload_1
13: iinc 1, -1
16: iadd
17: istore_2
18: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
21: iload_1
22: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
25: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
28: iload_2
29: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
32: return
LineNumberTable:
line 17: 0
line 18: 3
line 19: 18
line 20: 25
line 21: 32
LocalVariableTable:
Start Length Slot Name Signature
0 33 0 args [Ljava/lang/String;
3 30 1 a I
18 15 2 b I
}
SourceFile: "T03_ByteAnalyseAPlusPlus.java"
Process finished with exit code 0
分析:
- 注意:iinc指令是直接在局部变量槽位slot上进行运算
- a++ 和 ++a 的区别是先执行 iload 还是先执行 iinc
- a++是先加载iload,再自增iinc
- ++a是先自增iinc,再加载iload
下面我们通过字节码来剖析如下两行代码在内存当中整个执行过程
int a = 10;
int b = a++ + ++a + a--;
下图是先将10通过bipush 放入操作数栈中
接着将10从操作数栈上弹出存入局部变量表1号槽位,相当于代码 int a = 10 执行完成
接着执行:int b = a++ + ++a + a--; 因为有从左往右的执行顺序,所以先执行a++,先将a的值加载到操作数栈中;通过iload_1加载1号槽位的数据到操作数栈中
接着执行a++自增1操作,这个操作是在局部变量表中完成的。相当于完成了a++执行
再接着执行++a自增1操作,这个操作也是在局部变量表中完成的
接着从局部变量表1号槽位加载数据到操作数栈中,即12入栈,完成发a++ 、++a 各自的执行了
然后,iadd是将操作数栈中弹出(出栈)两个数12、10进行求和操作,得到22,最后将累加的结果22存入栈中。即完成了a++ + +aa的执行
接着,需要执行a--,先将局部变量表槽位1的数据12加载到操作数栈中
然后,将局部变量表槽位1的数据自减1
接着,执行iadd操作,将操作数栈12、22弹出栈后,进行求和操作得到34,再将34结果压入栈
最后,执行istore_2操作,将操作数栈弹出数据34,并压入局部变量表2号槽位中
文章最后,给大家推荐一些受欢迎的技术博客链接:
- Hadoop相关技术博客链接
- Spark 核心技术链接
- JAVA相关的深度技术博客链接
- 超全干货--Flink思维导图,花了3周左右编写、校对
- 深入JAVA 的JVM核心原理解决线上各种故障【附案例】
- 请谈谈你对volatile的理解?--最近小李子与面试官的一场“硬核较量”
- 聊聊RPC通信,经常被问到的一道面试题。源码+笔记,包懂
欢迎扫描下方的二维码或 搜索 公众号“10点进修”,我们会有更多、且及时的资料推送给您,欢迎多多交流!