你知道javap麼?

來源:互聯網
上載者:User

使用 javap 深入查看類檔案

Java 開發人員熟悉在一個迴圈中使用StringBuffer 來代替串聯 String 對象能獲得最佳效能。然而,多數開發人員從來沒有比較兩種方法產生的位元組代碼的區別。在 Java 開發套件(JDK)中有一個叫做 javap 的工具可以告訴你為什麼這樣做可以獲得最佳效能。

 
 
Javap 將一個類和它的方法的一些轉儲資訊輸出到標準輸出。該工具不把代碼反編譯為 java 原始碼,但是它會把位元組代碼反組譯碼成為由 JAVA 虛擬機器規範定義的位元組代碼指令。

在你需要查看編譯器為你或者給你做了什麼的時候,或者你想要看一處代碼的改動對編譯後的類檔案有什麼影響的時候,javap 相當有用。

現在以我們前面提到的 StringBuffer 和 String 作為一個例子。下面是一個專門為例子設計的類,它有兩個方法,都返回一個由0到 n 的數字組成的 String,其中 n 由調用者提供。兩個方法唯一的區別在於一個使用 String 構建結果,另外一個使用 StringBuffer 構建結果。

public class JavapTip {
    public static void main(String []args) {
    }

    private static String withStrings(int count) {
        String s = "";
        for (int i = 0; i < count; i++) {
            s += i;
        }

        return s;
    }

    private static String withStringBuffer(int count) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < count; i++) {
            sb.append(i);
        }

        return sb.toString();
    }
}

現在讓我們看看對這個類使用–c 選項運行 javap 的輸出。-c 選項告訴 javap 反組譯碼在類中遇到的位元組代碼。

運行方式如下:

>javap -c JavapTip

此命令的輸出為:

Method java.lang.String withStrings(int)
   0 ldc #2 <String "">
   2 astore_1
   3 iconst_0
   4 istore_2
   5 goto 30
   8 new #3 <Class java.lang.StringBuffer>
  11 dup
  12 invokespecial #4 <Method java.lang.StringBuffer()>
  15 aload_1
  16 invokevirtual #5 <Method java.lang.StringBuffer append(java.lang.String)>
  19 iload_2
  20 invokevirtual #6 <Method java.lang.StringBuffer append(int)>
  23 invokevirtual #7 <Method java.lang.String toString()>
  26 astore_1
  27 iinc 2 1
  30 iload_2
  31 iload_0
  32 if_icmplt 8
  35 aload_1
  36 areturn

Method java.lang.String withStringBuffer(int)
   0 new #3 <Class java.lang.StringBuffer>
   3 dup
   4 invokespecial #4 <Method java.lang.StringBuffer()>
   7 astore_1
   8 iconst_0
   9 istore_2
  10 goto 22
  13 aload_1
  14 iload_2
  15 invokevirtual #6 <Method java.lang.StringBuffer append(int)>
  18 pop
  19 iinc 2 1
  22 iload_2
  23 iload_0
  24 if_icmplt 13
  27 aload_1
  28 invokevirtual #7 <Method java.lang.String toString()>
  31 areturn

如果你以前沒有看過 Java 彙編器,那麼這個輸出對你來說就會比較難懂,但是你應該可以看到 withString 方法在每次迴圈的時候都新建立了一個 StringBuffer 執行個體。然後它將已有的 String 的當前值追加到 StringBuffer 上,然後追加迴圈的當前值。最後,它對 buffer 調用 toString 並將結果賦給現有的 String 引用。

withStringBuffer 方法與這個方法正好相反,在每次迴圈的時候 withStringBuffer 只調用現有 StringBuffer 的 append 方法,沒有建立新的對象,也沒有新的 String 引用。

在這種情況下,我們已經知道了使用 StringBuffer 代替 String 是一種好的做法,但是如果我們不知道呢?那麼 javap 可以協助我們找到答案。

你並不會經常需要一個 Java 反組譯碼器,但是當你需要的時候,知道你自己的機器已經有一個並且用法相當簡單的反組譯碼器當然是一件好事。如果你感興趣,看書看看 javap 的其它選項——或許你會發現在你的環境中需要的特性。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.