⭐️写在前面
这里是温文艾尔の学习之路
- 👍如果对你有帮助,给博主一个免费的点赞以示鼓励把QAQ
- 👋博客主页🎉 温文艾尔の学习小屋
- ⭐️更多文章👨🎓请关注温文艾尔主页📝
- 🍅文章发布日期:2022.02.06
- 👋java学习之路!
- 欢迎各位🔎点赞👍评论收藏⭐️
- 🎄新年快乐朋友们🎄
- 👋jvm学习之路!
- ⭐️上一篇内容:JVM04(类加载与字节码-图解方法执行流程)### 文章目录
1.i++
原始代码
publicclassDemo03{publicstaticvoidmain(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.classLast modified 2022年1月22日; size 599 bytes
SHA-256 checksum 2fb1f080d8858a312c0f3c65356a84fea66a987ae74607ef26ac5
aa49fbedfee
Compiled from "Demo03.java"publicclasscom.wql.jvm.ClassInfo.Demo03
minor version:0
major version:52
flags:(0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #4// com/wql/jvm/ClassInfo/Demo03
super_class: #5// java/lang/Object
interfaces:0, fields:0, methods:2, attributes:1Constant pool:
#1=Methodref #5.#22// java/lang/Object."<init>":()V
#2=Fieldref #23.#24// java/lang/System.out:Ljava/
io/PrintStream;
#3=Methodref #25.#26// java/io/PrintStream.println:(I)V
#4=Class #27// com/wql/jvm/ClassInfo/Demo03
#5=Class #28// java/lang/Object
#6=Utf8<init>
#7=Utf8()V
#8=Utf8Code
#9=Utf8LineNumberTable
#10=Utf8LocalVariableTable
#11=Utf8this
#12=Utf8Lcom/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=Utf8I
#19=Utf8 b
#20=Utf8SourceFile
#21=Utf8Demo03.java
#22=NameAndType #6:#7// "<init>":()V
#23=Class #29// java/lang/System
#24=NameAndType #30:#31// out:Ljava/io/PrintStream;
#25=Class #32// java/io/PrintStream
#26=NameAndType #33:#34// println:(I)V
#27=Utf8 com/wql/jvm/ClassInfo/Demo03
#28=Utf8 java/lang/Object
#29=Utf8 java/lang/System
#30=Utf8 out
#31=Utf8Ljava/io/PrintStream;
#32=Utf8 java/io/PrintStream
#33=Utf8 println
#34=Utf8(I)V{publiccom.wql.jvm.ClassInfo.Demo03();
descriptor:()V
flags:(0x0001) ACC_PUBLIC
Code:
stack=1, locals=1, args_size=10: aload_0
1: invokespecial #1// Method java/lang/Object."<init>":()V4:returnLineNumberTable:
line 9:0LocalVariableTable:StartLengthSlotNameSignature050thisLcom/wql/jvm/ClassInfo/Demo03;publicstaticvoidmain(java.lang.String[]);
descriptor:([Ljava/lang/String;)V
flags:(0x0009) ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=3, args_size=10: bipush 102: istore_1
3: iload_1
4: iinc 1,17: iinc 1,110: iload_1
11: iadd
12: iload_1
13: iinc 1,-116: iadd
17: istore_2
18: getstatic #2// Field java/lang/System.
out:Ljava/io/PrintStream;21: iload_1
22: invokevirtual #3// Method java/io/PrintStr
eam.println:(I)V25: getstatic #2// Field java/lang/System.
out:Ljava/io/PrintStream;28: iload_2
29: invokevirtual #3// Method java/io/PrintStr
eam.println:(I)V32:returnLineNumberTable:
line 11:0
line 12:3
line 13:18
line 14:25
line 15:32LocalVariableTable:StartLengthSlotNameSignature0330 args [Ljava/lang/String;3301 a I18152 b I}SourceFile:"Demo03.java"
本次我们主要分析这部分的操作
0: bipush 102: istore_1
3: iload_1
4: iinc 1,17: iinc 1,110: iload_1
11: iadd
12: iload_1
13: iinc 1,-116: 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
方法执行结束
版权归原作者 温文艾尔 所有, 如有侵权,请联系我们删除。