javap是jdk自带的一个工具,可以对代码反编译,也可以查看java编译器生成的字节码。
大家也可以自己去http://jd.benow.ca/官网下载对应操作系统的jd-gui工具
一般情况下,很少有人使用javap对class文件进行反编译,因为有很多成熟的反编译工具可以使用,比如jad。但是,javap还可以查看java编译器为我们生成的字节码。通过它,可以对照源代码和字节码,从而了解很多编译器内部的工作。
实例
javap命令分解一个class文件,它根据options来决定到底输出什么。如果没有使用options,那么javap将会输出包,类里的protected和public域以及类里的所有方法。javap
将会把它们输出在标准输出上。来看这个例子
C:\Users\Clarence>javap -c C:\Users\Clarence\Desktop\JavaPractice\SerializeDemo\bin\com\gouguocompany\serializedemo\SerializeDemo.class
Compiled from "SerializeDemo.java"
public class com.gouguocompany.serializedemo.SerializeDemo {
public com.gouguocompany.serializedemo.SerializeDemo();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #16 // class com/gouguocompany/serializedemo/Employee
3: dup
4: invokespecial #18 // Method com/gouguocompany/serializedemo/Employee."<init>":()V
7: astore_1
8: aload_1
9: ldc #19 // String Clarence
11: putfield #21 // Field com/gouguocompany/serializedemo/Employee.name:Ljava/lang/String;
14: aload_1
15: ldc #25 // String San Francisco
17: putfield #27 // Field com/gouguocompany/serializedemo/Employee.address:Ljava/lang/String;
20: aload_1
21: ldc #30 // int 11122333
23: putfield #31 // Field com/gouguocompany/serializedemo/Employee.SSN:I
26: aload_1
27: bipush 101
29: putfield #35 // Field com/gouguocompany/serializedemo/Employee.number:I
32: ldc #38 // String hello world
34: putstatic #40 // Field com/gouguocompany/serializedemo/Employee.test:Ljava/lang/String;
37: new #43 // class java/io/FileOutputStream
40: dup
41: ldc #45 // String /temp/employee.ser
43: invokespecial #47 // Method java/io/FileOutputStream."<init>":(Ljava/lang/String;)V
46: astore_2
47: new #50 // class java/io/ObjectOutputStream
50: dup
51: aload_2
52: invokespecial #52 // Method java/io/ObjectOutputStream."<init>":(Ljava/io/OutputStream;)V
55: astore_3
56: aload_3
57: aload_1
58: invokevirtual #55 // Method java/io/ObjectOutputStream.writeObject:(Ljava/lang/Object;)V
61: aload_3
62: invokevirtual #59 // Method java/io/ObjectOutputStream.close:()V
65: aload_2
66: invokevirtual #62 // Method java/io/FileOutputStream.close:()V
69: getstatic #63 // Field java/lang/System.out:Ljava/io/PrintStream;
72: ldc #69 // String Serialized data is saved in /tmp/employee.ser
74: invokevirtual #71 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
77: goto 85
80: astore_2
81: aload_2
82: invokevirtual #76 // Method java/lang/Exception.printStackTrace:()V
85: return
Exception table:
from to target type
37 77 80 Class java/lang/Exception
上面输出的内容就是字节码。
用法摘要
C:\Users\Clarence>Javap -help
用法: javap <options> <classes>
其中, 可能的选项包括:
-help --help -? 输出此用法消息
-version 版本信息
-v -verbose 输出附加信息
-l 输出行号和本地变量表
-public 仅显示公共类和成员
-protected 显示受保护的/公共类和成员
-package 显示程序包/受保护的/公共类
和成员 (默认)
-p -private 显示所有类和成员
-c 对代码进行反汇编
-s 输出内部类型签名
-sysinfo 显示正在处理的类的
系统信息 (路径, 大小, 日期, MD5 散列)
-constants 显示最终常量
-classpath <path> 指定查找用户类文件的位置
-cp <path> 指定查找用户类文件的位置
-bootclasspath <path> 覆盖引导类文件的位置
总结
javap可以用于反编译和查看编译器编译后的字节码。平时一般用javap -c
比较多,该命令用于列出每个方法所执行的JVM指令,并显示每个方法的字节码的实际作用。可以通过字节码和源代码的对比,深入分析java的编译原理,了解和解决各种Java原理级别的问题。