このテスト コードから:
public class Test {
public static void main(final String[] args) {
String temp = "a" + "b" + "c";
}
}
次のバイトコードを取得します。
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String abc
2: astore_1
3: return
この一定のプールでは:
Constant pool:
#1 = Methodref #4.#13 // java/lang/Object."<init>":()V
#2 = String #14 // abc
#3 = Class #15 // Test
#4 = Class #16 // java/lang/Object
#5 = Utf8 <init>
#6 = Utf8 ()V
#7 = Utf8 Code
#8 = Utf8 LineNumberTable
#9 = Utf8 main
#10 = Utf8 ([Ljava/lang/String;)V
#11 = Utf8 SourceFile
#12 = Utf8 Test.java
#13 = NameAndType #5:#6 // "<init>":()V
#14 = Utf8 abc
#15 = Utf8 Test
#16 = Utf8 java/lang/Object
だからあなたは間違っていました。1 つString
が作成され -- --実行時にプールに"abc"
配置されました。String
ここで、コンパイラは定数の折りたたみを実行し、コンパイル時の定数式"a" + "b" + "c"
を に簡略化しました"abc"
。-XD-printflat
コンパイラがバイトコードにコンパイルする実際のソースを示すフラグを使用してコンパイルすると、これを確認できます。
public static void main(final String[] args) {
String temp = "abc";
}
実際の連結を確認したい場合はString
、変数など、コンパイル時の定数ではないオペランドを使用する必要があります。
public static void main(final String[] args) {
String a = "a";
String b = "b";
String c = "c";
String temp = a + b + c;
}
次のようにコンパイルされます。
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String a
2: astore_1
3: ldc #3 // String b
5: astore_2
6: ldc #4 // String c
8: astore_3
9: new #5 // class java/lang/StringBuilder
12: dup
13: invokespecial #6 // Method java/lang/StringBuilder."<init>":()V
16: aload_1
17: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
20: aload_2
21: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
24: aload_3
25: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
28: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
31: astore 4
33: return