バイトコードの時間です!
class EmptyString {
public static void main(String[] args) {
String s = "any old string";
s += "";
}
}
javap -c EmptyString
:
Compiled from "EmptyString.java"
class EmptyString extends java.lang.Object{
EmptyString();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2; //String any old string
2: astore_1
3: new #3; //class java/lang/StringBuilder
6: dup
7: invokespecial #4; //Method java/lang/StringBuilder."":()V
10: aload_1
11: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
14: ldc #6; //String
16: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22: astore_1
23: return
}
あなたは+=
は関係なく、それが連結しているものの作成するStringBuilder
を引き起こし、それが実行時に最適化することができないことがわかります。
あなたは同じ式で両方の文字列リテラルを置く場合一方、それらはコンパイラによって連結されています
class EmptyString {
public static void main(String[] args) {
String s = "any old string" + "";
}
}
javap -c EmptyString
:
Compiled from "EmptyString.java"
class EmptyString extends java.lang.Object{
EmptyString();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2; //String any old string
2: astore_1
3: return
}
1 - greatjustice – Alex
のためのクールな。ありがとうございました! –
@ mmyers:1)放出されるバイトコードは(理論上は)Javaコンパイラ固有であり、2)JITコンパイラは(理論上は)さらに最適化できることを指摘しておきます。 –