javap,是JDK自带的反汇编工具,用于将Java字节码文件反汇编为Java源代码
也许我们很少会使用到javap工具,因为现在有很多好的反编译工具,但是我在此介绍这个工具不是使用它进行反编译,而是查看java编译器为我们生成 的字节码,通过比较字节码和源代码,我们可以发现很多的问题,一个很重要的作用就是了解很多编译器内部的工作机制,在笔者以前的几篇文章中就是借助此工具 的,本站有这些文章的原文《深入剖析java类的构造方式》和《使用String还是StringBuffer》。
下面我们通过具体的一个例子来简单的讲讲这个工具的作用,你不需要很深入的使用,这个简单的介绍和简单的使用就可以使你受益非浅。
源代码:
- class StringTest
- {
- public static void main(String[] args)
- {
- String result="";
- result+="ok";
- }
- }
在反编译前你当然需要先编译这个类了:javac -g StringTest.java(使用-g参数是因为要得到下面javap -l时的输出需要使用此选项)
编译完成后,我们在使用不同的选项看看不同的效果:
1、先看看最简单的不带参数的情况:javap StringTest:
- Compiled from StringTest.java
- class StringTest extends java.lang.Object {
- StringTest();
- public static void main(java.lang.String[]);
- }
不带参数的情况将答应类的public信息,包括成员和方法
从上面的输出中我们确定了两个知识:如果类没有显示的从其它类派生那么它就是从Object派生;如果没有为类显示的申明构造方法,那么编译器将为之生成一个缺省构造方法(不带参数的构造方法)
2、javap -c StringTest:
class StringTest extends java.lang.Object {
StringTest();
public static void main(java.lang.String[]);
}
Method StringTest()
0 aload_0
1 invokespecial #1 <Method java.lang.Object()>
4 return
Method void main(java.lang.String[])
0 ldc #2 <String "">
2 astore_1
3 new #3 <Class java.lang.StringBuffer>
6 dup
7 invokespecial #4 <Method java.lang.StringBuffer()>
10 aload_1
11 invokevirtual #5 <Method java.lang.StringBuffer append(java.lang.String)>
14 ldc #6 <String "ok">
16 invokevirtual #5 <Method java.lang.StringBuffer append(java.lang.String)>
19 invokevirtual #7 <Method java.lang.String toString()>
22 astore_1
23 return
带-p参数将额外的打印字节码信息
前面的和不带参数的输出一样,后面的显示了方法的具体的字节码,从这个输出里面我们又可以了解更多的内容,首先 是编译器生成的的缺省构造方法的内容为调用父类的构造方法super()(需要说明的是使用DJ反编译的源代码中这个缺省构造方法没有这个调用,这可能是 该反编译器的一种优化),main()方法的字节码信息的内容可以参考《使用String还是StringBuffer》一文的叙述。
3、javap -l StringTest :
class StringTest extends java.lang.Object {
StringTest();
public static void main(java.lang.String[]);
}
Line numbers for method StringTest()
line 1: 0
Local variables for method StringTest()
StringTest this pc=0, length=5, slot=0
Line numbers for method void main(java.lang.String[])
line 5: 0
line 6: 3
line 7: 23
Local variables for method void main(java.lang.String[])
java.lang.String[] args pc=0, length=24, slot=0
java.lang.String result pc=3, length=20, slot=1
-l参数将显示行号和局部变量表
从上面的输出中我们可以得到方法中的变量和方法的源代码对于字节码信息的,例如对应main()方法,它的变量为输入参数args以及局部变量 result,方法的源代码的第5行对应字节码的第0个偏移量,第5行对应字节码的第3个偏移量,而第7行对应字节码的第23偏移量(参看 javap -c的输出前面的偏移量),第7行实际是没有语句的,但是有一个隐含的return,而偏移量23实际对应的也是return调用
4、javap -p StringTest:
class StringTest extends java.lang.Object {
StringTest();
public static void main(java.lang.String[]);
}
-p参数将额外的打印private成员和方法的信息,因为这个类没有因此输出相同
这几个参数几乎就可以构成javap的最常使用的集合,最常用的应该还是-c选项,因为可以打印字节码的信息,关于这些字节码的详细涵义在Java 虚拟机规范中定义,感兴趣的可以查看相关的信息!
备上使用指南:
用法: javap <options> <classes> 可能的选项包括: -help --help -? 打印用法信息 -version 版本信息 -v -verbose 打印附加信息 -l 打印行号和本地变量表 -public 仅显示public类和成员 -protected 显示protected/public类和成员 -package 显示package/protected/public类和成员(默认值) -p -private 显示所有的类和成员 -c 反汇编代码 -s 打印内部类型签名 -sysinfo 显示将被处理的类的系统信息(路径,大小,日期,MD5 哈希值) -constants 显示static final常量 -classpath <path> 指定查找用户类文件的位置 -bootclasspath <path> 覆盖由引导类加载器所加载的类文件的位置
我们通常以如下形式使用javap:
1、不带任何可选参数(如果字节码文件就位于当前工作目录,可以不写类的包名):
#实际上等同于javap -package Person javap Person
2、反汇编指定目录下的字节码文件:
javap -classpath D:/java/lib cn.softown.Person
3、反汇编字节码文件为JVM可以识别、执行的字节码命令:
javap -c Person
以下是可选参数的详细说明:
javap -classpath D:\java\test Person
(即使DOS窗口的当前工作目录为其他任意路径,该命令均可正确执行)。javap -classpath D:\java\test -s Person
。jre\lib\ext
。例如:javap -classpath D:\java\test -extdirs D:\java\myext Person
javap -classpath D:\java\test -bootclasspath D:\java\core Person
javap -J-version
,可以有多个命令,中间以空格隔开。参考文章:
http://www.javaresearch.org/article/768.htm .
http://chenhua-1984.iteye.com/blog/423389
软件指南针(http://www.softown.cn)
相关推荐
如何使用javap反编译字节码
javap2p 技术内幕javap2p 技术内幕javap2p 技术内幕javap2p 技术内幕
总结javaP2P 编程中遇到的问题,以及P2P技术的核心问题,希望大家提出宝贵建议互相进步
Java运行原理 javap命令运行结果
用java写的记事本,程序很完整,有字体的格式和字体颜色这两大功能,界面采用javax里面的swing组件,很好看。
NULL 博文链接:https://bolinyang.iteye.com/blog/1830472
JavaP7架构师课程
sbt-javap 以下如上。概述sbt-javap是一个SBT插件,可以直接从SBT调用javap 。 Java提供了javap工具来反汇编和检查Java字节码。 这使作者可以查看其代码如何在较低级别上运行,了解如何对高级Scala概念进行编码以及...
ndk开发者对于javah和javap必用的,是否无法获取到签名,是否无法根据java代码生成c/c++中的头文件呢,那么就下载这个能指导你倒争取的方向
源文件 ---javac编译--> 字节码文件. 字节码文件 --javap反编译--> 源文件.
NULL 博文链接:https://josephmok.iteye.com/blog/813774
本篇文章给大家分享了关于JAVA中关于javap命令的使用技巧以及相关代码分享,有需要的朋友参考学习下。
JavaP2P技术内幕 太大不能上传,分5部分传递
JavaP2P技术内幕 太大不能上传,分5部分传递
JavaP2P技术内幕 太大不能上传,分5部分传递
chapter09多媒体与图形学程序设计JavaP.pptx
2022年优秀-chapter多媒体与图形学程序设计JavaP.pptx
使用c/c++实现javap的功能,加深对java中class结构的理解
本篇文章主要介绍了如何为eclipse配置javap命令,在配置过程中会出现的小问题的解决方法,非常实用,需要的朋友可以参考下
Javajavap工具的实现javap打印出传递给它的类的包,受保护的字段以及公共字段和方法。