为什么不问Java 类文件反汇编器-javap
每个 JDK 中包含的程序?
具有以下源代码:
public class Foo {
static void m1(Scanner scanner, String searchString, boolean result) {
while (scanner.hasNextLine() && !result) {
String line = scanner.nextLine();
result = line.indexOf(searchString) >= 0;
}
}
static void m2(Scanner scanner, String searchString, boolean result) {
while (scanner.hasNextLine() && !result) {
result = scanner.nextLine().indexOf(searchString) >= 0;
}
}
}
运行反汇编程序时:
javap -c Foo.class
你得到以下字节码:
static void m1(java.util.Scanner, java.lang.String, boolean);
Code:
0: goto 22
3: aload_0
4: invokevirtual #33 // Method java/util/Scanner.nextLine:()Ljava/lang/String;
7: astore_3
8: aload_3
9: aload_1
10: invokevirtual #39 // Method java/lang/String.indexOf:(Ljava/lang/String;)I
13: iflt 20
16: iconst_1
17: goto 21
20: iconst_0
21: istore_2
22: aload_0
23: invokevirtual #45 // Method java/util/Scanner.hasNextLine:()Z
26: ifeq 33
29: iload_2
30: ifeq 3
33: return
static void m2(java.util.Scanner, java.lang.String, boolean);
Code:
0: goto 20
3: aload_0
4: invokevirtual #33 // Method java/util/Scanner.nextLine:()Ljava/lang/String;
7: aload_1
8: invokevirtual #39 // Method java/lang/String.indexOf:(Ljava/lang/String;)I
11: iflt 18
14: iconst_1
15: goto 19
18: iconst_0
19: istore_2
20: aload_0
21: invokevirtual #45 // Method java/util/Scanner.hasNextLine:()Z
24: ifeq 31
27: iload_2
28: ifeq 3
31: return
如果您比较这两种方法的字节码,您会发现唯一的区别是m1
包含以下两条额外指令:
7: astore_3
8: aload_3
这只是将堆栈顶部对象的引用存储到局部变量中,仅此而已。
编辑:
反汇编器还可以显示方法的局部变量数量:
javap -l Foo.class
哪个输出:
static void m1(java.util.Scanner, java.lang.String, boolean);
LocalVariableTable:
Start Length Slot Name Signature
0 34 0 scanner Ljava/util/Scanner;
0 34 1 searchString Ljava/lang/String;
0 34 2 result Z
8 14 3 line Ljava/lang/String;
static void m2(java.util.Scanner, java.lang.String, boolean);
LocalVariableTable:
Start Length Slot Name Signature
0 32 0 scanner Ljava/util/Scanner;
0 32 1 searchString Ljava/lang/String;
0 32 2 result Z
}
这基本上证实了上面看到的唯一区别——这些m1
方法只分配了一个局部变量—— String line
。它不会再创建任何对象,它只会再创建一个对以任一方式分配的对象的引用。