1. 程式人生 > >Java i++ 和 ++i 的字節碼分析

Java i++ 和 ++i 的字節碼分析

陌生 位置 clas ava .class 發現 .html length ref

一、描述

想必大家對i++;++i的問題一定不會陌生;例如:

int j=0;
for(int i=0;i<100;i++) {
  j=j++;
}
System.out.println("j="+j);

但是聯系之前寫的一篇 JAVA 連等賦值問題 的博客,原以為產生差別的原因是棧中的引用導致的,結果查看 class 字節碼後發現不是,所以在這裏再分析一下;

二、分析

1. ++i

int j, i = 0;
j = ++i;

使用 javap -v .class查看字節碼;也可以使用 Jclasslib(一款 Class 文件的編輯器);

Code:
  stack=1, locals=3, args_size=1
    0: iconst_0          // 將0壓入操作數棧
    1: istore_2          // 將0存入本地變量表2的位置
    2: iinc       2, 1   // 本地變量表位置2加1
    5: iload_2           // 載入本地變量表2位置到操作數棧
    6: istore_1          // 存入本地變量表位置1
    7: return
  LocalVariableTable:
    Start  Length  Slot  Name   Signature
        0       8     0  args   [Ljava/lang/String;
        7       1     1     j   I     // j 為本地變量表1
        2       6     2     i   I     // i 為本地變量表2

如圖:

技術分享圖片

所以最終結果是: i=1;j=1;

2. i++

int j, i = 0;
j = i++;

同樣需要查看字節碼;

Code:
  stack=1, locals=3, args_size=1
    0: iconst_0
    1: istore_2
    2: iload_2
    3: iinc       2, 1
    6: istore_1
    7: return
  LineNumberTable:
    line 69: 0
    line 70: 2
    line 73: 7
  LocalVariableTable:
    Start  Length  Slot  Name   Signature
        0       8     0  args   [Ljava/lang/String;
        7       1     1     j   I
        2       6     2     i   I

技術分享圖片

所以最終結果是:i=1;j=0;

總結

  • 最終對比會發現 i++ 和 ++i,只有 iload_2 的位置不一樣;使得最終回寫到 j 位置的值不一樣;
  • 文中字節碼的含義是在《Java 虛擬機規範》中查找的;

Java i++ 和 ++i 的字節碼分析