??写在前面
这里是温文艾尔の学习之路 - 👍如果对你有帮助,给博主一个免费的点赞以示鼓励把QAQ
- 👋博客主页🎉 温文艾尔の学习小屋
- ??更多文章👨?🎓请关注温文艾尔主页📝
- 🍅文章发布日期:2022.02.06
- 👋java学习之路!
- 欢迎各位🔎点赞👍评论收藏??
- 🎄新年快乐朋友们🎄
- 👋jvm学习之路!
- ??上一篇内容:JVM04(类加载与字节码-图解方法执行流程)
1.i++
原始代码
public class Demo03 {
public static void main(String[] args) {
int a = 10;
int b = a++ + ++a + a--;
System.out.println(a);
System.out.println(b);
}
}
javap反编译后的.class字节码文件
Classfile /F:/2021年12月之后的Idea项目/jvmProject/out/production/jvmProj
ect/com/wql/jvm/ClassInfo/Demo03.class
Last modified 2022年1月22日; size 599 bytes
SHA-256 checksum 2fb1f080d8858a312c0f3c65356a84fea66a987ae74607ef26ac5
aa49fbedfee
Compiled from "Demo03.java"
public class com.wql.jvm.ClassInfo.Demo03
minor version: 0
major version: 52
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #4
3
super_class: #5
interfaces: 0, fields: 0, methods: 2, attributes: 1
Constant pool:
#1 = Methodref #5.#22
)V
#2 = Fieldref #23.#24
io/PrintStream;
#3 = Methodref #25.#26
:(I)V
#4 = Class #27
3
#5 = Class #28
#6 = Utf8 <init>
#7 = Utf8 ()V
#8 = Utf8 Code
#9 = Utf8 LineNumberTable
#10 = Utf8 LocalVariableTable
#11 = Utf8 this
#12 = Utf8 Lcom/wql/jvm/ClassInfo/Demo03;
#13 = Utf8 main
#14 = Utf8 ([Ljava/lang/String;)V
#15 = Utf8 args
#16 = Utf8 [Ljava/lang/String;
#17 = Utf8 a
#18 = Utf8 I
#19 = Utf8 b
#20 = Utf8 SourceFile
#21 = Utf8 Demo03.java
#22 = NameAndType #6:#7
#23 = Class #29
#24 = NameAndType #30:#31
#25 = Class #32
#26 = NameAndType #33:#34
#27 = Utf8 com/wql/jvm/ClassInfo/Demo03
#28 = Utf8 java/lang/Object
#29 = Utf8 java/lang/System
#30 = Utf8 out
#31 = Utf8 Ljava/io/PrintStream;
#32 = Utf8 java/io/PrintStream
#33 = Utf8 println
#34 = Utf8 (I)V
{
public com.wql.jvm.ClassInfo.Demo03();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1
."<init>":()V
4: return
LineNumberTable:
line 9: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/wql/jvm/ClassInfo/Demo03;
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x0009) 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
out:Ljava/io/PrintStream;
21: iload_1
22: invokevirtual #3
eam.println:(I)V
25: getstatic #2
out:Ljava/io/PrintStream;
28: iload_2
29: invokevirtual #3
eam.println:(I)V
32: return
LineNumberTable:
line 11: 0
line 12: 3
line 13: 18
line 14: 25
line 15: 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: "Demo03.java"
本次我们主要分析这部分的操作
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
分析:
- 注意iinc指令是直接在局部变量slot上进行运算
- a++和++a的区别是先执行iload还是先执行iinc
执行流程
1.bipush 10
含义:将10放入操作数栈中
2.istore_1
含义:弹出栈顶元素,放入局部变量槽的1号位置,对应a=10操作
然后开始执行a++的操作,a++顺序为先iload再自增
3.iload_1
将局部变量a=10压入操作栈栈顶 4.iinc 1 1
第一个参数是对哪个槽位做自增,第二个参数是自增多少 例如iinc 1 1意思是是局部变量表的1号槽位中的变量+1
下面开始++i的操作,顺序是先自增再iload
5.iinc 1 1
局部变量表的1号槽位中的变量+1,此时i=12 6.iload_1
将局部变量12压入操作数栈 7.iadd 弹出操作数栈栈顶的两个数字进行相加10+12 = 22,并将结果压入操作数栈 下面进行i–的操作 8.iload_1 将局部变量表1号槽位的变量压入栈顶 9.iinc 1 -1 对局部变量表1号槽位的变量进行-1操作 10.iadd 弹出栈顶的两个元素进行相加 istore 2 将栈顶元素弹出到局部变量表的2号槽位 故b=34,a=11 方法执行结束
|