为什么不询问Java类文件反汇编器 - 包含在每个JDK中的javap程序呢?
有以下源代码:
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
7: astore_3
8: aload_3
9: aload_1
10: invokevirtual
13: iflt 20
16: iconst_1
17: goto 21
20: iconst_0
21: istore_2
22: aload_0
23: invokevirtual
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
7: aload_1
8: invokevirtual
11: iflt 18
14: iconst_1
15: goto 19
18: iconst_0
19: istore_2
20: aload_0
21: invokevirtual
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
。 它不会创建任何其他对象,它只会创建一个对无论如何都分配的对象的另一个引用。
javap
工具自行查找。使用-c
选项反汇编两个版本的代码。如果两个版本的字节码完全相同,我不会感到惊讶。(事实上,如果它们不同,我会感到惊讶)。 - Jesper