如果您查看此方法
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
2: astore_1
3: ldc
5: astore_2
6: new
9: dup
10: aload_1
11: invokestatic
14: invokespecial
17: aload_2
18: invokevirtual
21: invokevirtual
...
并且
public void withFinal();
Code:
0: ldc
2: astore_1
3: ldc
5: astore_2
6: ldc
8: astore_3
...
因此,如果字符串不是final,则编译器将使用StringBuilder
来连接str1
和str2
,因此
String concat=str1+str2
将被编译为
String concat = new StringBuilder(str1).append(str2).toString();
这意味着concat
将在运行时创建,因此不会来自字符串池。
另外,如果字符串是final类型,则编译器可以假定它们永远不会更改,因此它可以安全地连接其值而无需使用StringBuilder
。
String concat = str1 + str2;
可以更改为
String concat = "str" + "ing";
并连接成
String concat = "string";
这意味着
concate
会成为字符串字面值,存储在字符串池中,并与相同的来自该池中字符串字面值进行比较,以供
if
语句使用。
equals()
和==
的区别,并且正在询问一个更有意义的问题。 - arshajiiString
,那该怎么办呢?我认为使用equals
进行内容比较非常合理,而使用==
进行身份比较。我们可以重写equals
方法来告诉程序什么情况下我们认为两个对象相等。如果使用==
进行内容比较,我们就无法重写它来定义“相等内容”的含义。而且,仅针对String
将equals
和==
的含义颠倒也是很愚蠢的。此外,无论如何,我也看不出使用==
进行内容比较有任何优势。 - SantiBailors