程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> 用Javap反編譯幫你理解Java特性

用Javap反編譯幫你理解Java特性

編輯:JAVA編程入門知識
  Java 開發人員熟悉在一個循環中使用StringBuffer 來代替串聯 String 對象能獲得最佳性能。然而,多數開發人員從來沒有比較兩種方法產生的字節代碼的區別。在 Java 開發工具包(JDK)中有一個叫做 javap 的工具可以告訴你為什麼這樣做可以獲得最佳性能。
     
   <!-- frame contents --> <!-- /frame contents -->   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();
     }
     }

     現在讓我們看看對這個類使用?Cc 選項運行 javap 的輸出。-c 選項告訴 javap 反匯編在類中碰到的字節代碼。
     
     運行方式如下:
     
     > javap -c JavapTip
     
     此命令的輸出為:
     
     Method java.lang.String withStrings(int)
     0 ldc #2
     2 astore_1
     3 iconst_0
     4 istore_2
     5 goto 30
     8 new #3
     11 dup
     12 invokespecial #4
     15 aload_1
     16 invokevirtual #5
     19 iload_2
     20 invokevirtual #6
     23 invokevirtual #7
     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
     3 dup
     4 invokespecial #4
     7 astore_1
     8 iconst_0
     9 istore_2
     10 goto 22
     13 aload_1
     14 iload_2
     15 invokevirtual #6
     18 pop
     19 iinc 2 1
     22 iload_2
     23 iload_0
     24 if_icmplt 13
     27 aload_1
     28 invokevirtual #7
     31 areturn

     假如你以前沒有看過 Java 匯編器,那麼這個輸出對你來說就會比較難懂,但是你應該可以看到 withString 方法在每次循環的時候都新創建了一個 StringBuffer 實例。然後它將已有的 String 的當前值追加到 StringBuffer 上,然後追加循環的當前值。最後,它對 buffer 調用 toString 並將結果賦給現有的 String 引用。
     
     withStringBuffer 方法與這個方法正好相反,在每次循環的時候 withStringBuffer 只調用現有 StringBuffer 的 append 方法,沒有創建新的對象,也沒有新的 String 引用。
 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved