javap是jdk自帶的一個工具,能夠對代碼反編譯,也能夠查看java編譯器生成的字節碼。java
通常狀況下,不多有人使用javap對class文件進行反編譯,由於有不少成熟的反編譯工具可使用,好比jad。可是,javap還能夠查看java編譯器爲咱們生成的字節碼。經過它,能夠對照源代碼和字節碼,從而瞭解不少編譯器內部的工做。app
javap命令分解一個class文件,它根據options來決定到底輸出什麼。若是沒有使用options,那麼javap將會輸出包,類裏的protected和public域以及類裏的全部方法。javap
將會把它們輸出在標準輸出上。來看這個例子,先編譯(javac
)下面這個類。工具
import java.awt.*; import java.applet.*; public class DocFooter extends Applet { String date; String email; public void init() { resize(500,100); date = getParameter("LAST_UPDATED"); email = getParameter("EMAIL"); } public void paint(Graphics g) { g.drawString(date + " by ",100, 15); g.drawString(email,290,15); } }
在命令行上鍵入javap DocFooter後,輸出結果以下ui
Compiled from "DocFooter.java" public class DocFooter extends java.applet.Applet { java.lang.String date; java.lang.String email; public DocFooter(); public void init(); public void paint(java.awt.Graphics); }
若是加入了-c,即javap -c DocFooter,那麼輸出結果以下spa
Compiled from "DocFooter.java" public class DocFooter extends java.applet.Applet { java.lang.String date; java.lang.String email; public DocFooter(); Code: 0: aload_0 1: invokespecial #1 // Method java/applet/Applet."<init>":()V 4: return public void init(); Code: 0: aload_0 1: sipush 500 4: bipush 100 6: invokevirtual #2 // Method resize:(II)V 9: aload_0 10: aload_0 11: ldc #3 // String LAST_UPDATED 13: invokevirtual #4 // Method getParameter:(Ljava/lang/String;)Ljava/lang/String; 16: putfield #5 // Field date:Ljava/lang/String; 19: aload_0 20: aload_0 21: ldc #6 // String EMAIL 23: invokevirtual #4 // Method getParameter:(Ljava/lang/String;)Ljava/lang/String; 26: putfield #7 // Field email:Ljava/lang/String; 29: return public void paint(java.awt.Graphics); Code: 0: aload_1 1: new #8 // class java/lang/StringBuilder 4: dup 5: invokespecial #9 // Method java/lang/StringBuilder."<init>":()V 8: aload_0 9: getfield #5 // Field date:Ljava/lang/String; 12: invokevirtual #10 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 15: ldc #11 // String by 17: invokevirtual #10 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 20: invokevirtual #12 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 23: bipush 100 25: bipush 15 27: invokevirtual #13 // Method java/awt/Graphics.drawString:(Ljava/lang/String;II)V 30: aload_1 31: aload_0 32: getfield #7 // Field email:Ljava/lang/String; 35: sipush 290 38: bipush 15 40: invokevirtual #13 // Method java/awt/Graphics.drawString:(Ljava/lang/String;II)V 43: return }
上面輸出的內容就是字節碼。命令行
-help 幫助 -l 輸出行和變量的表 -public 只輸出public方法和域 -protected 只輸出public和protected類和成員 -package 只輸出包,public和protected類和成員,這是默認的 -p -private 輸出全部類和成員 -s 輸出內部類型簽名 -c 輸出分解後的代碼,例如,類中每個方法內,包含java字節碼的指令, -verbose 輸出棧大小,方法參數的個數 -constants 輸出靜態final常量
javap能夠用於反編譯和查看編譯器編譯後的字節碼。平時通常用javap -c
比較多,該命令用於列出每一個方法所執行的JVM指令,並顯示每一個方法的字節碼的實際做用。能夠經過字節碼和源代碼的對比,深刻分析java的編譯原理,瞭解和解決各類Java原理級別的問題。code