/**
* 從位元組碼角度分析 a++ 相關題目
*/
public class Demo3_12_3 {
public static void main(String[] args) {
int a = 10;
int b = a++;
}
}
生成的位元組碼
Classfile /F:/BaiduNetdiskDownload/JVM/2019-解密JVM資料/代碼/jvm/out/production/jvm/cn/itcast/jvm/t3/bytecode/Demo3_12_3.class
Last modified 2021-2-28; size 473 bytes
MD5 checksum 924e6b2ead1874ed36a1757db8fc4ecd
Compiled from "Demo3_12_3.java"
public class cn.itcast.jvm.t3.bytecode.Demo3_12_3
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #3.#20 // java/lang/Object."<init>":()V
#2 = Class #21 // cn/itcast/jvm/t3/bytecode/Demo3_12_3
#3 = Class #22 // java/lang/Object
#4 = Utf8 <init>
#5 = Utf8 ()V
#6 = Utf8 Code
#7 = Utf8 LineNumberTable
#8 = Utf8 LocalVariableTable
#9 = Utf8 this
#10 = Utf8 Lcn/itcast/jvm/t3/bytecode/Demo3_12_3;
#11 = Utf8 main
#12 = Utf8 ([Ljava/lang/String;)V
#13 = Utf8 args
#14 = Utf8 [Ljava/lang/String;
#15 = Utf8 a
#16 = Utf8 I
#17 = Utf8 b
#18 = Utf8 SourceFile
#19 = Utf8 Demo3_12_3.java
#20 = NameAndType #4:#5 // "<init>":()V
#21 = Utf8 cn/itcast/jvm/t3/bytecode/Demo3_12_3
#22 = Utf8 java/lang/Object
{
public cn.itcast.jvm.t3.bytecode.Demo3_12_3();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 6: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcn/itcast/jvm/t3/bytecode/Demo3_12_3;
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=3, args_size=1
0: bipush 10 //把10壓入操作數棧中
2: istore_1 //把10(操作數棧頂資料)存儲在局部變量表的1号位上
3: iload_1 //把局部變量表1号位上的資料壓到操作數棧中,但是局部變量表還是會保留住資料并不會因為壓到操作數棧之後資料就沒有了
4: iinc 1, 1 //此時進行++操作,因為這個++操作是在局部變量表中進行的,是以此時局部變量表上的資料為11,但是操作數棧中的資料為10
7: istore_2
8: return
LineNumberTable:
line 8: 0
line 9: 3
line 10: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 args [Ljava/lang/String;
3 6 1 a I
8 1 2 b I
}
SourceFile: "Demo3_12_3.java"
/**
* 從位元組碼角度分析 a++ 相關題目
*/
public class Demo3_12_4 {
public static void main(String[] args) {
int a = 10;
int b = ++a;
}
}
生成的位元組碼
Classfile /F:/BaiduNetdiskDownload/JVM/2019-解密JVM資料/代碼/jvm/out/production/jvm/cn/itcast/jvm/t3/bytecode/Demo3_12_4.class
Last modified 2021-2-28; size 473 bytes
MD5 checksum eba48d8bd84e156b984607b002110fc6
Compiled from "Demo3_12_4.java"
public class cn.itcast.jvm.t3.bytecode.Demo3_12_4
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #3.#20 // java/lang/Object."<init>":()V
#2 = Class #21 // cn/itcast/jvm/t3/bytecode/Demo3_12_4
#3 = Class #22 // java/lang/Object
#4 = Utf8 <init>
#5 = Utf8 ()V
#6 = Utf8 Code
#7 = Utf8 LineNumberTable
#8 = Utf8 LocalVariableTable
#9 = Utf8 this
#10 = Utf8 Lcn/itcast/jvm/t3/bytecode/Demo3_12_4;
#11 = Utf8 main
#12 = Utf8 ([Ljava/lang/String;)V
#13 = Utf8 args
#14 = Utf8 [Ljava/lang/String;
#15 = Utf8 a
#16 = Utf8 I
#17 = Utf8 b
#18 = Utf8 SourceFile
#19 = Utf8 Demo3_12_4.java
#20 = NameAndType #4:#5 // "<init>":()V
#21 = Utf8 cn/itcast/jvm/t3/bytecode/Demo3_12_4
#22 = Utf8 java/lang/Object
{
public cn.itcast.jvm.t3.bytecode.Demo3_12_4();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 6: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcn/itcast/jvm/t3/bytecode/Demo3_12_4;
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=3, args_size=1
0: bipush 10
2: istore_1
3: iinc 1, 1
6: iload_1
7: istore_2
8: return
LineNumberTable:
line 8: 0
line 9: 3
line 10: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 args [Ljava/lang/String;
3 6 1 a I
8 1 2 b I
}
SourceFile: "Demo3_12_4.java"
其實 i++ 和 ++i 的差別就在 iinc 和 iload_1 的先後順序。
如果在後面都加上System.out.println(a);
這個時候就會增加點位元組碼
8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
11: iload_1 //這裡其實又重新把局部變量表上的 11 壓倒操作數棧中,此時a的值就會變成11
12: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
public static void main(String[] args) {
int i = 0;
int x = 0;
while (i < 10) {
x = x++; // 因為這個x++ 會先執行iload,把操作數棧上的值0重新放到本地變量表中,導緻x的值一直為0
i++;
}
System.out.println(x); // 結果是 0
}