a = a++與 a = ++a詳解
阿新 • • 發佈:2019-02-07
以前對a++與++a的理解僅限於:
a = a++先賦值後計算,a = ++a先計算後賦值。
單從應用的角度來講,這麼簡單理解是沒有問題的。
這篇部落格用來深入理解並測試二者真正的區別。一句話說到前頭,
a = a++與a = ++a均為先計算後賦值,不同的是:
a = a++中變數先壓棧,後計算,最後棧頂元素彈出賦值於a;
a = ++a中變數先計算,後壓棧,最後棧頂元素彈出賦值於a。
詳解如下:
先了解一些反編譯的基礎知識:
JVM指令詳解,可以看這兩篇部落格:部落格1 部落格2
在這裡我們只需要瞭解幾個指令就行:
助記符 說明
iconst_1 : 將int 型(1)推送至棧頂
istore_1 : 將棧頂int型數值存入第二個本地變數。(main方法中,第一個本地變數是String[] args,第二個開始才是自己定義的變數)
iload_1 : 將int型陣列指定索引的值推送至棧頂(在下面的測試程式碼中,指的就是變數a,即把a的值壓入棧頂)
iinc 1, 1: 該指令第一引數為本地變數的編號,第二個引數為自增減的數量。(這裡的意思就是將本地第二個變數(int型)的值+1
a = a++
測試程式碼:
public class test{
public static void main(String[] args) {
int a=1;
a = a++;
System.out.println(a);
}
}
反編譯結果:
反編譯結果解釋:
a = a++;
Code:
0: iconst_1 棧頂:1 a: 0
1: istore_1 棧頂:已彈出該元素 a: 1
2: iload_1 棧頂:1 a: 1
3: iinc 1, 1 棧頂:1 a: 2
6: istore_1 棧頂:已彈出該元素 a: 1
7: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
10: iload_1 棧頂:1
11: invokevirtual #3 取棧頂元素輸出1 // Method java/io/PrintStream.println:(I)V
14: return
a = ++a
測試程式碼:
public class test{
public static void main(String[] args) {
int a=1;
a = ++a;
System.out.println(a);
}
}
反編譯結果:
反編譯結果解釋:
a = ++a;
Code:
0: iconst_1 棧頂:1 a: 0
1: istore_1 棧頂:已彈出該元素 a: 1
2: iinc 1, 1 棧頂:已彈出該元素 a: 2
5: iload_1 棧頂:2 a: 2
6: istore_1 棧頂:已彈出該元素 a: 2
7: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
10: iload_1 棧頂:2
11: invokevirtual #3 取棧頂元素輸出2 // Method java/io/PrintStream.println:(I)V
14: return