語法:
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做字符串的例子。
- 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方法中,是循環拼接字符串。也是我們預想的步驟在執行。