- 浏览: 443624 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
g_man1990:
update config 不成功啊
build-helper-maven-plugin 配置多 source resource 文件 -
netwelfare:
文章很详细,就是太长了,读起来有点困难,倒不如写精练点,像这篇 ...
Java 基本类型 -
huyuancai1010:
function commitForm() {
var ...
加时间戳或者随机数去除js缓存 -
Smile__:
不过这个东西以前还真没研究过 。
hibernate.jdbc.fetch_size 和 hibernate.jdbc.batch_size -
Smile__:
想不到你也是北大青鸟的 。哈
hibernate.jdbc.fetch_size 和 hibernate.jdbc.batch_size
javap是jdk自带的一个工具,可以反编译,也可以查看java编译器生成的字节码,是分析代码的一个好工具。
下面我们通过具体的一个例子来简单的讲讲这个工具的作用,你不需要很深入的使用,这个简单的介绍和简单的使用就可以使你受益非浅。
源代码:
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:
Compiled from StringTest.java
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 :
Compiled from StringTest.java
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:
Compiled from StringTest.java
class StringTest extends java.lang.Object {
StringTest();
public static void main(java.lang.String[]);
}
-p参数将额外的打印private成员和方法的信息,因为这个类没有因此输出相同
这几个参数几乎就可以构成javap的最常使用的集合,最常用的应该还是-c选项,因为可以打印字节码的信息,关于这些字节码的具体涵义在Java 虚拟机规范中定义.
String Or Stringbuffer
Java 开发人员熟悉在一个循环中使用StringBuffer 来代替串联 String 对象能获得最佳性能。然而,多数开发人员从来没有比较两种方法产生的字节代码的区别。在 Java 开发工具包(JDK)中有一个叫做 javap 的工具可以告诉你为什么这样做可以获得最佳性能。
Javap 将一个类和它的方法的一些转储信息输出到标准输出。该工具不把代码反编译为 java 源代码,但是它会把字节代码反汇编成为由 Java 虚拟机规范定义的字节代码指令。
在你需要查看编译器为你或者给你做了什么的时候,或者你想要看一处代码的改动对编译后的类文件有什么影响的时候,javap 相当有用。
现在以我们前面提到的 StringBuffer 和 String 作为一个例子。下面是一个专门为例子设计的类,它有两个方法,都返回一个由0到 n 的数字组成的 String,其中 n 由调用者提供。两个方法唯一的区别在于一个使用 String 构建结果,另外一个使用 StringBuffer 构建结果。
public class JavapTip {
public static void main(String []args) {
}
private static String withStrings(int count) {
String s = "";
for (int i = 0; i < count; i++) {
s += i;
}
return s;
}
private static String withStringBuffer(int count) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < count; i++) {
sb.append(i);
}
return sb.toString();
}
}
现在让我们看看对这个类使用–c 选项运行 javap 的输出。-c 选项告诉 javap 反汇编在类中遇到的字节代码。
运行方式如下:
>javap -c JavapTip
此命令的输出为:
Method java.lang.String withStrings(int)
0 ldc #2
2 astore_1
3 iconst_0
4 istore_2
5 goto 30
8 new #3
11 dup
12 invokespecial #4
15 aload_1
16 invokevirtual #5
19 iload_2
20 invokevirtual #6
23 invokevirtual #7
26 astore_1
27 iinc 2 1
30 iload_2
31 iload_0
32 if_icmplt 8
35 aload_1
36 areturn
Method java.lang.String withStringBuffer(int)
0 new #3
3 dup
4 invokespecial #4
7 astore_1
8 iconst_0
9 istore_2
10 goto 22
13 aload_1
14 iload_2
15 invokevirtual #6
18 pop
19 iinc 2 1
22 iload_2
23 iload_0
24 if_icmplt 13
27 aload_1
28 invokevirtual #7
31 areturn
如果你以前没有看过 Java 汇编器,那么这个输出对你来说就会比较难懂,但是你应该可以看到 withString 方法在每次循环的时候都新创建了一个 StringBuffer 实例。然后它将已有的 String 的当前值追加到 StringBuffer 上,然后追加循环的当前值。最后,它对 buffer 调用 toString 并将结果赋给现有的 String 引用。
withStringBuffer 方法与这个方法正好相反,在每次循环的时候 withStringBuffer 只调用现有 StringBuffer 的 append 方法,没有创建新的对象,也没有新的 String 引用。
在这种情况下,我们已经知道了使用 StringBuffer 代替 String 是一种好的做法,但是如果我们不知道呢?那么 javap 可以帮助我们找到答案。在这里你可以看到更详细的关于String,StringBuffer 的解释
你并不会经常需要一个 Java 反汇编器,但是当你需要的时候,知道你自己的机器已经有一个并且用法相当简单的反汇编器当然是一件好事。如果你感兴趣,看书看看 javap 的其它选项——或许你会发现在你的环境中需要的特性。
发表评论
-
StringBuStringffer 和 StringBuilder 区别
2010-02-05 17:37 1388String 字符串常量 StringBuffer 字符串变量 ... -
Java timezone
2010-01-13 20:57 1679转自:行者买刀 获得java时间时,突然获得的时间不是当前 ... -
JAVA 主动调用与被动调用
2009-12-31 13:54 2293public class Test { stati ... -
Java解析XML文件的方法比较
2009-12-24 17:14 13401)DOM(JAXP Crimson解 ... -
Java 遍历二叉树
2009-12-18 17:13 1983Binary.java import java.util.S ... -
Java protected
2009-12-16 15:17 4741(1)除了在(2)中表 ... -
ConcurrentHashMap
2009-12-15 11:40 1843关键字: concurrenthashmap ... -
SimpleDateFormat 参数 Z
2009-12-11 17:20 1683import java.text.SimpleDate ... -
HashMap 详解
2009-12-04 14:30 1413Hashmap是一种非常常用的、应用广泛的数据类型,最近研究到 ... -
JAVA自动装箱与拆箱
2009-11-24 17:15 1644自动装箱与拆箱的功能事实上是编译器来帮您的忙,编译器在编译时期 ... -
String java
2009-11-24 16:29 1439众所周知,String是由字符组成的串,在程序中使用频率很高。 ... -
Java 动态绑定
2009-09-08 11:45 1496代码: public class Par ... -
JAVA虚拟机命令行参数
2009-08-18 15:51 1983一、运行class文件执行带main方法的class文件,命令 ... -
Collections.sort
2009-07-03 16:59 1690第一种方法:容器内要排序的类必须时下Comparable接口: ... -
java 多态 例子
2009-06-30 21:58 2673其实也就是两种绑定状态:动态绑定(也称后期绑定),静态绑定(也 ... -
Java 字节 字符 字符串
2009-06-23 10:07 5999String的length()方法和数组的length属性 S ... -
Java 运算符 详解
2009-06-23 09:59 2137有些运算符在JAVA语言中存在着,但是在实际开发中我们或许很少 ... -
Java 面试题 经典
2009-06-22 16:42 1676请下载见附件~~~ -
Java 基本类型
2009-06-22 16:39 32279基本类型,或者叫做内置类型,是JAVA中不同于类的特殊类型。它 ... -
java 传值 传引用
2009-06-22 16:18 1767JAVA中的传递都是值传递吗?有没有引用传递呢? 在回答这两个 ...
相关推荐
如何使用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打印出传递给它的类的包,受保护的字段以及公共字段和方法。