学习JVM知识看到JAVAP可以反编译出Class的二进制文件,很是好奇,收集网上资料以备学习。
描述:
javap命令分解一个class文件,它根据options来决定到底输出什么。如果没有使用options,那么javap将会输出包,类里的protected和public域以及类里的所有方法。javap将会把它们输出在标准输出上。来看这个例子,先编译下面这个类。
- 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后,输出结果如下
- 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,那么输出结果如下
- 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);
- }
- Method DocFooter()
- 0 aload_0
- 1 invokespecial #1
- 4 return
- Method void init()
- 0 aload_0
- 1 sipush 500
- 4 bipush 100
- 6 invokevirtual #2
- 9 aload_0
- 10 aload_0
- 11 ldc #3
- 13 invokevirtual #4
- 16 putfield #5
- 19 aload_0
- 20 aload_0
- 21 ldc #6
- 23 invokevirtual #4
- 26 putfield #7
- 29 return
- Method void paint(java.awt.Graphics)
- 0 aload_1
- 1 new #8
- 4 dup
- 5 invokespecial #9
- 8 aload_0
- 9 getfield #5
- 12 invokevirtual #10
- 15 ldc #11
- 17 invokevirtual #10
- 20 invokevirtual #12
- 23 bipush 100
- 25 bipush 15
- 27 invokevirtual #13
- 30 aload_1
- 31 aload_0
- 32 getfield #7
- 35 sipush 290
- 38 bipush 15
- 40 invokevirtual #13
- 43 return
当然,如果想分析这个文件,可以讲输出结果输出到一个文件里。可以这样写
javap -c DocFooter > F://test.txt
这样就会输出到F盘的test.txt文件中了。
选项:
-help 不说了
-l 输出行和变量的表
-public 只输出public方法和域
-protected 只输出public和protected类和成员
-package 只输出包,public和protected类和成员,这是默认的
-private 输出所有类和成员
-s 输出内部类型签名
-c 输出分解后的代码,例如,类中每一个方法内,包含java字节码的指令,
-verbose 输出栈大小,方法参数的个数