javap的基本用法

javap 是JDK自带的反汇编器,可以查看java编译器为我们生成的字节码。通过它,我们可以对照源代码和字节码,从而了解很多编译器内部的工作。
语法:
   javap [ 命令选项 ] class. . .
   javap 命令用于解析类文件。其输出取决于所用的选项。若没有使用选项, javap 将输出传递给它的类的 public 域及方法。 javap 将其输出到标准输出设备上。
命令选项
  -help 输出 javap 的帮助信息。
  -l 输出行及局部变量表。
  -b 确保与 JDK 1.1 javap 的向后兼容性。
  -public 只显示 public 类及成员。
  -protected 只显示 protected 和 public 类及成员。
  -package 只显示包、protected 和 public 类及成员。这是缺省设置。
  -private 显示所有类和成员。
  -J[flag] 直接将 flag 传给运行时系统。
  -s 输出内部类型签名。
  -c 输出类中各方法的未解析的代码,即构成 Java 字节码的指令。
  -verbose 输出堆栈大小、各方法的 locals 及 args 数,以及class文件的编译版本
  -classpath[路径] 指定 javap 用来查找类的路径。如果设置了该选项,则它将覆盖缺省值或 CLASSPATH 环境变量。目录用冒号分隔。
   -bootclasspath[路径] 指定加载自举类所用的路径。缺省情况下,自举类是实现核心 Java 平台的类,位于 jrelib下面。

  -extdirs[dirs] 覆盖搜索安装方式扩展的位置。扩展的缺省位置是 jrelibext。


C:\Users\soft>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>    覆盖引导类文件的位置

示例:

下面也经典的StringBuilder代替String做字符串的例子。

public class JAVAPTest {
	public static void main(String[] args) {

	}

	public static String contactWithStringNoLoopNoPara() {
		String s = "This is " + " my " + "first JAVAP test code.";
		return s;
	}
	
	public static String contactWithStringNoLoop(int count) {
		String s = "This is " + " my " + count + "th JAVAP test code.";
		return s;
	}
	
	public static String contactWithStringLoop(int count) {
		String s = "";
		for (int i = 0; i < count; i++) {
			s += i;
		}
		return s;
	}

	public static String contactWithStringBufferLoop(int count) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < count; i++) {
			sb.append(i);
		}
		return sb.toString();
	}
}

先编译:javac JAVAPTest.java

执行反编译:javap -c JAVAPTest         //注意这个地方不需要class后缀。

结果如下:

Compiled from "JAVAPTest.java"
public class JAVAPTest extends java.lang.Object{
public JAVAPTest();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   return

public static java.lang.String contactWithStringNoLoopNoPara();
  Code:
   0:   ldc     #2; //String This is  my first JAVAP test code.
   2:   astore_0
   3:   aload_0
   4:   areturn

public static java.lang.String contactWithStringNoLoop(int);
  Code:
   0:   new     #3; //class java/lang/StringBuilder
   3:   dup
   4:   invokespecial   #4; //Method java/lang/StringBuilder."<init>":()V
   7:   ldc     #5; //String This is  my
   9:   invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   12:  iload_0
   13:  invokevirtual   #7; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
   16:  ldc     #8; //String th JAVAP test code.
   18:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   21:  invokevirtual   #9; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   24:  astore_1
   25:  aload_1
   26:  areturn

public static java.lang.String contactWithStringLoop(int);
  Code:
   0:   ldc     #10; //String
   2:   astore_1
   3:   iconst_0
   4:   istore_2
   5:   iload_2
   6:   iload_0
   7:   if_icmpge       35
   10:  new     #3; //class java/lang/StringBuilder
   13:  dup
   14:  invokespecial   #4; //Method java/lang/StringBuilder."<init>":()V
   17:  aload_1
   18:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   21:  iload_2
   22:  invokevirtual   #7; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
   25:  invokevirtual   #9; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   28:  astore_1
   29:  iinc    2, 1
   32:  goto    5
   35:  aload_1
   36:  areturn

public static java.lang.String contactWithStringBufferLoop(int);
  Code:
   0:   new     #11; //class java/lang/StringBuffer
   3:   dup
   4:   invokespecial   #12; //Method java/lang/StringBuffer."<init>":()V
   7:   astore_1
   8:   iconst_0
   9:   istore_2
   10:  iload_2
   11:  iload_0
   12:  if_icmpge       27
   15:  aload_1
   16:  iload_2
   17:  invokevirtual   #13; //Method java/lang/StringBuffer.append:(I)Ljava/lang/StringBuffer;
   20:  pop
   21:  iinc    2, 1
   24:  goto    10
   27:  aload_1
   28:  invokevirtual   #14; //Method java/lang/StringBuffer.toString:()Ljava/lang/String;
   31:  areturn

}

有这个结果我们可以知道。

1。contactWithStringNoLoopNoPara方法中,代码里面是字符串拼接,貌似需要是用StringBuilder替换的好。其实在看了上面的反编译结果后,已经自动组合成一个固定字符串了。因此完全没有必要使用StringBuilder。


 0:   ldc     #2; //String This is  my first JAVAP test code.



2。contactWithStringNoLoop方法中,因为使用到了变量,貌似需要是用StringBuilder替换的好。其实在看了上面的反编译结果后,已经自动使用了StringBuilder。所以代码也没有必要使用StringBuilder。


3. contactWithStringLoop方法中,是循环拼接字符串,貌似需要是用StringBuilder替换的好。看了反编译后,每个循环里面都各自生成了一个StringBuilder,并将StringBuilder.toString()防赋值给我们的Sring变量。而我们希望的是只生成一个StringBuilder对象。因此改为StringBuilder的好。循环的时候改为contactWithBufferLoop的方法最好。


4.contactWithBufferLoop方法中,是循环拼接字符串。也是我们预想的步骤在执行。


转自:http://blog.csdn.net/hantiannan/article/details/7659904












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值