轉自http://blog.csdn.net/hantiannan/article/category/589614

javap是JDK自帶的反匯編器,可以查看java編譯器為我們生成的字節碼。通過它,我們可以對照源代碼和字節碼,從而了解很多編譯器內部的工作。
語法:
  javap [ 命令選項 ] class. . .
  javap 命令用于解析類文件。其輸出取決于所用的選項。若沒有使用選項,javap將輸出傳遞給它的類的 public 域及方法。javap 將其輸出到標準輸出設備上。
命令選項
  -help 輸出 javap 的幫助信息。
  -l 輸出行及局部變量表。
  -b 確保與 JDK 1.1 javap 的向后兼容性。
  -public 只顯示 public 類及成員。
  -protected 只顯示 protected 和 public 類及成員。
  -package 只顯示包、protected 和 public 類及成員。這是缺省設置。
  -private 顯示所有類和成員。
  -J[flag] 直接將 flag 傳給運行時系統。
  -s 輸出內部類型簽名。
  -c 輸出類中各方法的未解析的代碼,即構成 Java 字節碼的指令。
  -verbose 輸出堆棧大小、各方法的 locals 及 args 數,以及class文件的編譯版本
  -classpath[路徑] 指定 javap 用來查找類的路徑。如果設置了該選項,則它將覆蓋缺省值或 CLASSPATH 環境變量。目錄用冒號分隔。
  -bootclasspath[路徑] 指定加載自舉類所用的路徑。缺省情況下,自舉類是實現核心Java 平臺的類,位于 jrelib下面。

  -extdirs[dirs] 覆蓋搜索安裝方式擴展的位置。擴展的缺省位置是 jrelibext。


英文說明:

C:\>javap -help
Usage: javap <options> <classes>...

where options include:
   -c                        Disassemble the code
   -classpath <pathlist>     Specify where to find user class files
   -extdirs <dirs>           Override location of installed extensions
   -help                     Print this usage message
   -J<flag>                  Pass <flag> directly to the runtime system
   -l                        Print line number and local variable tables
   -public                   Show only public classes and members
   -protected                Show protected/public classes and members
   -package                  Show package/protected/public classes
                             and members (default)
   -private                  Show all classes and members
   -s                        Print internal type signatures
   -bootclasspath <pathlist> Override location of class files loaded
                             by the bootstrap class loader
   -verbose                  Print stack size, number of locals and args for methods
                             If verifying, print reasons for failure


示例:

下面也經典的StringBuilder代替String做字符串的例子。

  1. public class JAVAPTest { 
  2.     public static void main(String[] args) { 
  3.  
  4.     } 
  5.  
  6.     public static String contactWithStringNoLoopNoPara() { 
  7.         String s = "This is " + " my " + "first JAVAP test code."
  8.         return s; 
  9.     } 
  10.      
  11.     public static String contactWithStringNoLoop(int count) { 
  12.         String s = "This is " + " my " + count + "th JAVAP test code."
  13.         return s; 
  14.     } 
  15.      
  16.     public static String contactWithStringLoop(int count) { 
  17.         String s = ""
  18.         for (int i = 0; i < count; i++) { 
  19.             s += i; 
  20.         } 
  21.         return s; 
  22.     } 
  23.  
  24.     public static String contactWithStringBufferLoop(int count) { 
  25.         StringBuffer sb = new StringBuffer(); 
  26.         for (int i = 0; i < count; i++) { 
  27.             sb.append(i); 
  28.         } 
  29.         return sb.toString(); 
  30.     } 


 


先編譯:javac JAVAPTest.java

執行反編譯:javap -c JAVAPTest         //注意這個地方不需要class后綴。

結果如下:

  1. Compiled from "JAVAPTest.java" 
  2. public class JAVAPTest extends java.lang.Object{ 
  3. public JAVAPTest(); 
  4.   Code: 
  5.    0:   aload_0 
  6.    1:   invokespecial   #1; //Method java/lang/Object."<init>":()V 
  7.    4:   return 
  8.  
  9. public static void main(java.lang.String[]); 
  10.   Code: 
  11.    0:   return 
  12.  
  13. public static java.lang.String contactWithStringNoLoopNoPara(); 
  14.   Code: 
  15.    0:   ldc     #2; //String This is  my first JAVAP test code. 
  16.    2:   astore_0 
  17.    3:   aload_0 
  18.    4:   areturn 
  19.  
  20. public static java.lang.String contactWithStringNoLoop(int); 
  21.   Code: 
  22.    0:   new     #3; //class java/lang/StringBuilder 
  23.    3:   dup 
  24.    4:   invokespecial   #4; //Method java/lang/StringBuilder."<init>":()V 
  25.    7:   ldc     #5; //String This is  my 
  26.    9:   invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
  27.    12:  iload_0 
  28.    13:  invokevirtual   #7; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 
  29.    16:  ldc     #8; //String th JAVAP test code. 
  30.    18:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
  31.    21:  invokevirtual   #9; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
  32.    24:  astore_1 
  33.    25:  aload_1 
  34.    26:  areturn 
  35.  
  36. public static java.lang.String contactWithStringLoop(int); 
  37.   Code: 
  38.    0:   ldc     #10; //String 
  39.    2:   astore_1 
  40.    3:   iconst_0 
  41.    4:   istore_2 
  42.    5:   iload_2 
  43.    6:   iload_0 
  44.    7:   if_icmpge       35 
  45.    10new     #3; //class java/lang/StringBuilder 
  46.    13:  dup 
  47.    14:  invokespecial   #4; //Method java/lang/StringBuilder."<init>":()V 
  48.    17:  aload_1 
  49.    18:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
  50.    21:  iload_2 
  51.    22:  invokevirtual   #7; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 
  52.    25:  invokevirtual   #9; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
  53.    28:  astore_1 
  54.    29:  iinc    2, 1 
  55.    32goto    5 
  56.    35:  aload_1 
  57.    36:  areturn 
  58.  
  59. public static java.lang.String contactWithStringBufferLoop(int); 
  60.   Code: 
  61.    0:   new     #11; //class java/lang/StringBuffer 
  62.    3:   dup 
  63.    4:   invokespecial   #12; //Method java/lang/StringBuffer."<init>":()V 
  64.    7:   astore_1 
  65.    8:   iconst_0 
  66.    9:   istore_2 
  67.    10:  iload_2 
  68.    11:  iload_0 
  69.    12:  if_icmpge       27 
  70.    15:  aload_1 
  71.    16:  iload_2 
  72.    17:  invokevirtual   #13; //Method java/lang/StringBuffer.append:(I)Ljava/lang/StringBuffer; 
  73.    20:  pop 
  74.    21:  iinc    2, 1 
  75.    24goto    10 
  76.    27:  aload_1 
  77.    28:  invokevirtual   #14; //Method java/lang/StringBuffer.toString:()Ljava/lang/String; 
  78.    31:  areturn 
  79.  

有這個結果我們可以知道。

 

1。contactWithStringNoLoopNoPara方法中,代碼里面是字符串拼接,貌似需要是用StringBuilder替換的好。其實在看了上面的反編譯結果后,已經自動組合成一個固定字符串了。因此完全沒有必要使用StringBuilder。

  1. 0:   ldc     #2; //String This is  my first JAVAP test code. 

 

2。contactWithStringNoLoop方法中,因為使用到了變量,貌似需要是用StringBuilder替換的好。其實在看了上面的反編譯結果后,已經自動使用了StringBuilder。所以代碼也沒有必要使用StringBuilder。


3. contactWithStringLoop方法中,是循環拼接字符串,貌似需要是用StringBuilder替換的好。看了反編譯后,每個循環里面都各自生成了一個StringBuilder,并將StringBuilder.toString()防賦值給我們的Sring變量。而我們希望的是只生成一個StringBuilder對象。因此改為StringBuilder的好。循環的時候改為contactWithBufferLoop的方法最好。


4.contactWithBufferLoop方法中,是循環拼接字符串。也是我們預想的步驟在執行。