Wenn ich dieses Snippet kompiliere.Wie erfolgt die Verkettung der letzten Strings in Java?
public class InternTest {
public static void main(String...strings){
final String str1="str";
final String str2="ing";
String str= str1+str2;
}
}
, das die folgende Bytecode
public static void main(java.lang.String...);
flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS
Code:
stack=1, locals=4, args_size=1
0: ldc #16 // String str
2: astore_1
3: ldc #18 // String ing
5: astore_2
6: ldc #20 // String string
8: astore_3
9: return
so Stringliteral "string" produziert, ist schon da in dem konstanten Pool, die 6: ldc #20 // String string
auf Stapel an dieser Linie geschoben wird.
JSL Zitiert
Von JLS §4.12.4 - final Variablen:
Eine Variable vom Urtyp oder String-Typ, das ist endgültig und mit einem Kompilierung-konstanten Ausdruck initialisiert (§ 15.28), wird eine konstante Variable genannt.
Auch von JLS §15.28 - ConstantExpression:
Compile-Zeit konstanter Ausdrücke vom Typ String sind immer "interniert" um eindeutige Instanzen zu teilen, die Methode String # intern verwendet().
So weiß ich, str1 und str2 wird in dem Moment interniert werden sie erstellt wurde. „Str“ und „ing“ den gleichen Speicher in Zeile teilen String str= str1+str2;
Aber wie str1 + str2 produziert direkt „string“ in der konstante String Pool. Ohne irgendeine String Builder-Klasse aufzurufen, wie wenn ich final
nicht schreibe.? Um zu sehen, ob es etwas zu tun mit intern Dinge bekommen hat
ich diesen Schnipsel schrieb
public class IntermTest {
public static void main(String...strings){
String str1=("str").intern();
String str2=("ing").intern();
String str= str1+str2;
}
}
Aber wenn ich den Bytecode erzeugt bekam ich dieses
public static void main(java.lang.String...);
flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS
Code:
stack=3, locals=4, args_size=1
0: ldc #16 // String str
2: invokevirtual #18 // Method java/lang/String.intern:
()Ljava/lang/String;
5: astore_1
6: ldc #24 // String ing
8: invokevirtual #18 // Method java/lang/String.intern:
()Ljava/lang/String;
11: astore_2
12: new #26 // class java/lang/StringBuilder
15: dup
16: aload_1
17: invokestatic #28 // Method java/lang/String.valueOf
:(Ljava/lang/Object;)Ljava/lang/String;
20: invokespecial #32 // Method java/lang/StringBuilder.
"<init>":(Ljava/lang/String;)V
23: aload_2
24: invokevirtual #35 // Method java/lang/StringBuilder.
append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
27: invokevirtual #39 // Method java/lang/StringBuilder.
toString:()Ljava/lang/String;
30: astore_3
31: return
Tat es nutzt auch stringBuilder
für Verkettung. Also hat es etwas mit Finale zu tun. Gibt es etwas Besonderes an final
Saiten, denen ich definitiv nicht bewusst bin?
Etwas sagt mir, dass dies die Antwort sein wird Ihre nächste Frage: http://Stackoverflow.com/a/19418517/1393766 – Pshemo
@Pshemo, wenn dies klar geworden ist ..ich glaube nicht, dass das ein Problem verursacht hätte .. Wie auch immer, danke für so nette Frage .. :) Jede Frage ist eine große Lernkurve! –