Java 從字節碼的角度談代碼優化的假象

專欄原創出處:github-源筆記文件 github-源碼 ,歡迎 Star,轉載請附上原文出處鏈接和本聲明。

Java 核心知識專欄系列筆記,系統性學習可訪問個人覆盤筆記-技術博客 Java 核心知識

個人想法

總結此文章源於以前對代碼格式書寫的誤解。

for 裏面外面聲明對象問題

// 方式一:Object 聲明在 for 外部
public void forObjectOutline() {
    Object o;
    for (int i = 0; i < 10; i++) {
        o = new Object();
        System.out.println(o);
    }
}

// 方式二:Object 聲明在 for 內部
public void forObjectInline() {
    for (int i = 0; i < 10; i++) {
        Object o = new Object();
        System.out.println(o);
    }
}

上面的代碼哪種寫法性能更優?答案是都一樣。最終生成的字節碼爲方式二的寫法。

因爲不管你在哪兒聲明的對象 o,虛擬機中的棧幀只爲這個 o 創建一個對應的局部變量槽。for 裏面的 new 操作只是一直將
o 引用重新指向新的對象而已。

方式二字節碼如下:

Code:(字節碼)
  stack=2, locals=3, args_size=1
     0: iconst_0
     1: istore_2
     2: iload_2
     3: bipush        10
     5: if_icmpge     29    for 的條件判斷
     8: new           #3    new java/lang/Object
    11: dup                 賦值一份 new 出來的引用
    12: invokespecial #1    調用構造方法 java/lang/Object."<init>":()V
    15: astore_1            將棧頂引用型數值(剛剛 new 出來的對象)存入第二個本地變量。即局部變量表中的 o
    16: getstatic     #4    
    19: aload_1
    20: invokevirtual #5    
    23: iinc          2, 1
    26: goto          2
    29: return
  LocalVariableTable:(局部變量表)
    Start  Length  Slot  Name   Signature
       16      13     1     o   Ljava/lang/Object;
        2      27     2     i   I
        0      30     0  this   Lio/groud/leetcode/algorithms/_bytecode/S;

更多相關專欄內容彙總:

發佈了270 篇原創文章 · 獲贊 55 · 訪問量 38萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章