1. 程式人生 > 實用技巧 >位元組碼中的常用指令

位元組碼中的常用指令

一道面試題,問最後輸出多少?
 public static void main(String[] args) {
        int a = 10;
        a = a++; // 輸出10
        //a = ++a; // 輸出11
        System.out.println(a);
    }
上述程式碼對應的位元組碼指令

​ 一個main方法對應虛擬機器棧的一個棧幀,下面所說的運算元棧就是棧幀中的運算元棧。對變數進行數學運算或者賦值等操作都要把運算元彈出棧。

使用a = a++ 後位元組碼的指令

  1. bipush : 將10 壓入運算元棧
  2. istore_1:將10出棧,並賦值給區域性變量表中下標為1(下標為0的是 this 變數)的變數a,完成賦值語句。
  3. iload_1:因為要對a進行賦值操作,把10壓入運算元棧。
  4. iinc 1 by 1:但是在上一步最終完成賦值之前,要對a進行++操作,所以直接將區域性變量表中下標為1即變數a進行加1,此時a = 11。
  5. istore_1:將運算元的的數彈出並賦值給a,a 又變成了10。所以最後輸出10
使用a = ++a後的位元組碼指令

  1. bipush 10: 將10壓入運算元棧
  2. istore_1:將10出棧,並賦值給區域性變量表中下標為1的變數a,完成賦值語句。
  3. iinc 1 by 1:因為這裡是先自加再賦值,所以將a + 1變成11。
  4. iload_1:現在執行賦值操作,所以先讓11入運算元棧。
  5. istore_1:讓11出棧,給a賦值。最終a = 11。
常用指令總結
  1. bipush: 壓棧

  2. iload_x:將區域性變量表中下標為x壓入棧

  3. istore_x:將棧定資料彈出,賦值給區域性變數中下標為x的變數

  4. iadd:將棧頂兩個元素彈出,進行相加操作

  5. isub:將棧頂兩個元素彈出,進行相減操作

  6. invokespecial:執行特殊方法,即不需要多型的方法。

    ​ 例如:private方法、構造方法

  7. invokevirtual:呼叫方法

  8. invokestatic:執行靜態方法

.....