すべての JDK に含まれているプログラムであるJavaクラス ファイル逆アセンブラーについて質問してみませんか?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 #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
2 つのメソッドのバイトコードを比較すると、唯一の違いは、m1
次の 2 つの追加命令が含まれていることです。
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
メソッドはもう1つのローカル変数のみを割り当てます- String line
. これ以上オブジェクトを作成することはありません。いずれかの方法で割り当てられたオブジェクトへの参照をもう 1 つ作成するだけです。