參考:http://www.cnblogs.com/beautiful-code/p/6424977.html
javap是JDK自帶的反匯編器,可以查看java編譯器為我們生成的字節碼。通過它,我們可以對照源代碼和字節碼,從而了解很多編譯器內部的工作。
語法:
英文說明:
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做字符串的例子。
public class JAVAPTest { public static void main(String[] args) { } public static String contactWithStringNoLoopNoPara() { String s = "This is " + " my " + "first JAVAP test code."; return s; } public static String contactWithStringNoLoop(int count) { String s = "This is " + " my " + count + "th JAVAP test code."; return s; } public static String contactWithStringLoop(int count) { String s = ""; for (int i = 0; i < count; i++) { s += i; } return s; } public static String contactWithStringBufferLoop(int count) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < count; i++) { sb.append(i); } return sb.toString(); } }
先編譯:javac JAVAPTest.java
執行反編譯:javap -c JAVAPTest //注意這個地方不需要class后綴。
結果如下:
Compiled from "JAVAPTest.java" public class JAVAPTest extends java.lang.Object{ public JAVAPTest(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: return public static java.lang.String contactWithStringNoLoopNoPara(); Code: 0: ldc #2; //String This is my first JAVAP test code. 2: astore_0 3: aload_0 4: areturn public static java.lang.String contactWithStringNoLoop(int); Code: 0: new #3; //class java/lang/StringBuilder 3: dup 4: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V 7: ldc #5; //String This is my 9: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 12: iload_0 13: invokevirtual #7; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 16: ldc #8; //String th JAVAP test code. 18: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 21: invokevirtual #9; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 24: astore_1 25: aload_1 26: areturn public static java.lang.String contactWithStringLoop(int); Code: 0: ldc #10; //String 2: astore_1 3: iconst_0 4: istore_2 5: iload_2 6: iload_0 7: if_icmpge 35 10: new #3; //class java/lang/StringBuilder 13: dup 14: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V 17: aload_1 18: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 21: iload_2 22: invokevirtual #7; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 25: invokevirtual #9; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 28: astore_1 29: iinc 2, 1 32: goto 5 35: aload_1 36: areturn public static java.lang.String contactWithStringBufferLoop(int); Code: 0: new #11; //class java/lang/StringBuffer 3: dup 4: invokespecial #12; //Method java/lang/StringBuffer."<init>":()V 7: astore_1 8: iconst_0 9: istore_2 10: iload_2 11: iload_0 12: if_icmpge 27 15: aload_1 16: iload_2 17: invokevirtual #13; //Method java/lang/StringBuffer.append:(I)Ljava/lang/StringBuffer; 20: pop 21: iinc 2, 1 24: goto 10 27: aload_1 28: invokevirtual #14; //Method java/lang/StringBuffer.toString:()Ljava/lang/String; 31: areturn }
有這個結果我們可以知道。
1。contactWithStringNoLoopNoPara方法中,代碼里面是字符串拼接,貌似需要是用StringBuilder替換的好。其實在看了上面的反編譯結果后,已經自動組合成一個固定字符串了。因此完全沒有必要使用StringBuilder。
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方法中,是循環拼接字符串。也是我們預想的步驟在執行。
