在前面的文章中,有详细地介绍java字节码相关的知识,有兴趣的可以提前了解一下。
下面我们将以字节码的视角来分析判断结果
// 从字节码角度来分析:判断结果
public class T08_ByteAnalyseJudgeResult {
public static void main(String[] args) {
int i = 0 ;
int x = 0;
while (i < 10) {
x = x++;
i++;
}
System.out.println(x); // 结果是0
}
}
T08_ByteAnalyseJudgeResult 字节码:使用javap -v T08_ByteAnalyseJudgeResult.class,将java程序对应的字节码如下,并做了执行的注释。
0: iconst_0 // int型常量值0进栈
1: istore_1 // 将栈顶int型数值存入第二个局部变量,从0开始计数 (1号槽位 i)
2: iconst_0 // int型常量值0进栈
3: istore_2 // 将栈顶元素存入第三个本地变量 (2号槽位 x)
4: iload_1 // 第二个int型局部变量进栈,从0开始计数
5: bipush 10 // 将一个byte型常量值推送至栈顶
7: if_icmpge 21 // 比较栈顶两int型数值大小,当结果大于等于0时跳转 [while (i < 10)]
10: iload_2 // 将第三个int型数值推送到栈顶
11: iinc 2, 1 // 指定int型变量增加指定值 指定2号槽位加1,即自增1
14: istore_2 // 将栈顶元素存入2号槽位,局部变量表中
15: iinc 1, 1 // 指定int型变量增加指定值
18: goto 4 // 无条件跳转
21: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; // 获取指定类的静态域,并将其值压入栈顶
24: iload_2 // 将第三个int型数值推送到栈顶
25: invokevirtual #3 // Method java/io/PrintStream.println:(I)V // 调用实例方法
28: return // 当前方法返回void
为了更好说明:x = x++ 执行后为什么还是原来的值,特别原理图说明。如下:
总结:
- x = x++ 操作是先从局部变量表中取数据到栈顶
- 然后局部变量表数据自增1
- 最后从栈顶弹数据出来存入局部变量表中
所以:x = x++,最终结果还是和之前的初始数据值是致。
文章最后,给大家推荐一些受欢迎的技术博客链接:
- Hadoop相关技术博客链接
- Spark 核心技术链接
- JAVA相关的深度技术博客链接
- 超全干货--Flink思维导图,花了3周左右编写、校对
- 深入JAVA 的JVM核心原理解决线上各种故障【附案例】
- 请谈谈你对volatile的理解?--最近小李子与面试官的一场“硬核较量”
- 聊聊RPC通信,经常被问到的一道面试题。源码+笔记,包懂
欢迎扫描下方的二维码或 搜索 公众号“10点进修”,我们会有更多、且及时的资料推送给您,欢迎多多交流!