深入理解JVM之--字節碼

       上篇講到棧幀,現在我們需要了解棧幀的執行過程,那就涉及到反編譯字節碼。

一. 反編譯代碼

(1)源代碼

/**
 * 編譯:javac com\jvm\StackFrame.java
 * 反編譯:javap -p -v com\jvm\StackFrame.class
 */
public class StackFrame {
    public static void main(String[] args) {
        add(1, 2);
    }

    private static int add(int a, int b) {
        int c = 0;
        c = a + b;
        return c;
    }
}

(2)反編譯後的字節碼,不懂沒關係,接下來進行字節碼解釋。

{
  public com.jvm.StackFrame();
    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 7: 0

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: iconst_1
         1: iconst_2
         2: invokestatic  #2                  // Method add:(II)I
         5: pop
         6: return
      LineNumberTable:
        line 9: 0
        line 10: 6

  private static int add(int, int);
    descriptor: (II)I
    flags: ACC_PRIVATE, ACC_STATIC
    Code:
      stack=2, locals=3, args_size=2
         0: iconst_0
         1: istore_2
         2: iload_0
         3: iload_1
         4: iadd
         5: istore_2
         6: iload_2
         7: ireturn
      LineNumberTable:
        line 13: 0
        line 14: 2
        line 15: 6
}

2. 字節碼解釋

(1)# 方法描述
# 括號內爲入數類型,這裏爲兩個 int 型入參
# 括號外爲返回類型,這裏爲返回 int 型
descriptor: (II)I

# 方法類型,這裏爲私有的靜態方法
flags: ACC_PRIVATE, ACC_STATIC


# 操作數棧爲 2
# 本地變量容量爲 3
# 入參個數爲 2
stack=2, locals=3, args_size=2

執行 add(1,2) 的過程,最後 ireturn 會將操作數棧棧頂的值返回給調用者

代碼行號與字節碼行號的對應關係

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