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:\>javap -help
Usage: javap <options> <classes>...
where options include:
-c Disassemble the code
-classpath <pathlist> Specify where to find user class files
-extdirs <dirs> Override location of installed extensions
-help Print this usage message
-J<flag> Pass <flag> directly to the runtime system
-l Print line number and local variable tables
-public Show only public classes and members
-protected Show protected/public classes and members
-package Show package/protected/public classes
and members (default)
-private Show all classes and members
-s Print internal type signatures
-bootclasspath <pathlist> Override location of class files loaded
by the bootstrap class loader
-verbose Print stack size, number of locals and args for methods
If verifying, print reasons for failure
示例:
下面也经典的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();
- }
- }
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;
- 4: return
-
- public static void main(java.lang.String[]);
- Code:
- 0: return
-
- public static java.lang.String contactWithStringNoLoopNoPara();
- Code:
- 0: ldc #2;
- 2: astore_0
- 3: aload_0
- 4: areturn
-
- public static java.lang.String contactWithStringNoLoop(int);
- Code:
- 0: new #3;
- 3: dup
- 4: invokespecial #4;
- 7: ldc #5;
- 9: invokevirtual #6;
- 12: iload_0
- 13: invokevirtual #7;
- 16: ldc #8;
- 18: invokevirtual #6;
- 21: invokevirtual #9;
- 24: astore_1
- 25: aload_1
- 26: areturn
-
- public static java.lang.String contactWithStringLoop(int);
- Code:
- 0: ldc #10;
- 2: astore_1
- 3: iconst_0
- 4: istore_2
- 5: iload_2
- 6: iload_0
- 7: if_icmpge 35
- 10: new #3;
- 13: dup
- 14: invokespecial #4;
- 17: aload_1
- 18: invokevirtual #6;
- 21: iload_2
- 22: invokevirtual #7;
- 25: invokevirtual #9;
- 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;
- 3: dup
- 4: invokespecial #12;
- 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;
- 20: pop
- 21: iinc 2, 1
- 24: goto 10
- 27: aload_1
- 28: invokevirtual #14;
- 31: areturn
-
- }
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方法中,是循环拼接字符串。也是我们预想的步骤在执行。