如果你看看这个方法
public void noFinal() {
String str1 = "str";
String str2 = "ing";
String concat = str1 + str2;
System.out.println(concat == "string");
}
public void withFinal() {
final String str1 = "str";
final String str2 = "ing";
String concat = str1 + str2;
System.out.println(concat == "string");
}
javap -c ClassWithTheseMethods
并使用您将看到的版本进行反编译
public void noFinal();
Code:
0: ldc #15 // String str
2: astore_1
3: ldc #17 // String ing
5: astore_2
6: new #19 // class java/lang/StringBuilder
9: dup
10: aload_1
11: invokestatic #21 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
14: invokespecial #27 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
17: aload_2
18: invokevirtual #30 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual #34 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
...
和
public void withFinal();
Code:
0: ldc #15 // String str
2: astore_1
3: ldc #17 // String ing
5: astore_2
6: ldc #44 // String string
8: astore_3
...
所以如果字符串不是最终的编译器将不得不使用StringBuilder
连接str1
等str2
String concat=str1+str2;
将被编译为
String concat = new StringBuilder(str1).append(str2).toString();
这意味着concat
它将在运行时创建,因此不会来自字符串池。
此外,如果字符串是最终的,那么编译器可以假设它们永远不会改变,因此StringBuilder
可以安全地连接它的值而不是使用它
String concat = str1 + str2;
可以改为
String concat = "str" + "ing";
并连接成
String concat = "string";
这意味着concate
它将成为字符串字面量,将在字符串池中实习,然后在if
语句中与该池中的相同字符串字面量进行比较。