java字節碼淺學

參考
字節碼指令 : http://gityuan.com/2015/10/24/jvm-bytecode-grammar/

從字節碼角度分析 i++ 和 ++i 實現 : http://www.lxweimin.com/p/7988e646a37e

java代碼:

public class ByteCodeDemo {
    public static void main(String[] args) {
        int i = 1;
        int j = 5;

        int dj = ++j;
        int di = i++;

        System.out.println(di);
        System.out.println(dj);
    }
}

class反編譯后:

Compiled from "ByteCodeDemo.java"
public class com.mpt.pomdemo.test.ByteCodeDemo {
  public com.mpt.pomdemo.test.ByteCodeDemo();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: iconst_1
       1: istore_1
       2: iconst_5
       3: istore_2
       4: iinc          2, 1
       7: iload_2
       8: istore_3
       9: iload_1
      10: iinc          1, 1
      13: istore        4
      15: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      18: iload         4
      20: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
      23: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      26: iload_3
      27: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
      30: return
}

  • load 命令:用于將局部變量表的指定位置的相應類型變量加載到棧頂;
  • store命令:用于將棧頂的相應類型數據保入局部變量表的指定位置;

iconst_1 int型常量1進棧

istore_1 棧頂int數值存入變量表中的第2個位置

iconst_5 int型常量5進棧

istore_2 棧頂int數值存入變量表中的第3個位置

iinc 2, 1 將變量表中第3個位置加一

iload_2 將變量2進棧(下方 i++ 操作沒有這一步,所以i++還是沒執行加一操作的值)

istore_3 棧頂int數值存入第4局部變量

iload_1 將變量1進棧

iinc 1, 1 將變量表中第二個位置加一

istore 棧頂int數值存入第1局部變量

...

通過這個簡單的例子學習java class文件反編譯之后的命令在棧幀中的局部變量表和操作數棧中所作的操作,還有要注意指令的標號,并不是連續的,也就是有些操作并沒有展現出來

java的跨平臺特性:
javac命令:把.java文件編譯為class文件
java命令:jvm把class文件根據當前的操作系統 執行對應的操作
即編譯后的class文件無需修改即可實現跨平臺的特性

為什么JVM不直接把源碼解析成機器碼去執行?
1 準備工作:每次執行都需要各種檢查
2 兼容性 : 也可以將別的語言解析成字節碼

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。