JVM 字節碼指令對於棧幀數據操作舉例

    這一篇其實是對前面一篇《JVM字節碼執行模型及字節碼指令集》的一個延續和舉例。結合例子看一下條件判定和無條件跳轉指令對虛擬機棧的數據操作。

 

    我們先來看一段代碼例子。這裏addEspresso()添加濃度方法會判斷參數,如果參數<=1那麼久拋出異常。

package bytecode;

/**
 *
 * Created by yunshen.ljy on 2015/6/21.
 */
public class CaramelMacchiato {

    private int espresso ;

    public void addEspresso(int espresso) {
        if (espresso > 1) {
            this.espresso = espresso;
        } else {
            throw new IllegalArgumentException();
        }
    }

}

    然後看一下addEspresso方法的字節碼如下:

   0:        iload_1

   1:        iconst_1

   2:        if_icmple  13

   5:        aload_0

   6:        iload_1

   7:        putfield    #2; //Field espresso:I

   10:      goto 21

   13:      new #3; //class java/lang/IllegalArgumentException

   16:      dup

   17:      invokespecial   #4; //Method java/lang/IllegalArgumentException."<init>":()V

   20:      athrow

   21:      return

 

    這裏我們來對字節碼指令進行解析。

    第一行和第二行指令分別是把參數espresso以及常量1 從局部變量表壓入操作數棧。

    第三行指令,也就是條件語句的比較指令,比較操作數棧頂,第一條第二條指令對應的值的大小,如果不滿足比較條件,就會跳轉到字節碼的13 這個位置。也即是進入到異常處理。

    第四行指令到第六行指令就是我們前面一篇介紹過的,如同setBean 方法一樣的。對於field的賦值操作。

    第五行 goto 指令,無條件跳轉到所制定的21的位置,方法返回,清空方法棧。

    第六行開始是異常處理。這裏先是new 指令創建一個Exception對象,並且將其壓入操作數棧。

    第七行指令複製剛纔的對象,並且壓入操作數棧。

    第八行是將其中一個Exception對象出棧,病調用其構造器方法。

    第九行將另外一個對象出棧,並且拋出異常,所以也是清空、結束了當前的方法棧。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章