2

以下代码段中的代码只是比较字符串引用。

String str1 = "mystring9";
String str2 = "mystring"+String.valueOf(9);

System.out.println(str1==str2);

在这种情况下,str1==str2返回false


以下代码段也返回false.

String str1 = "mystring9";
String str2="mystring"+str1.length();

System.out.println(str1==str2);

但是,以下代码返回true.

String str1 = "mystring9";
String str2 = "mystring"+9;

System.out.println(str1==str2);

我认为,"mystring"+9这段代码中的表达式应该在内部进行评估,String.valueOf(9)但为什么前两个示例返回的输出与前面的示例不同?

4

6 回答 6

3

Java 编译器将预先评估所有仅常量操作。(这称为常量折叠

因此,"A" + "b" + 3编译为"Ab3".

于 2013-10-25T14:18:32.300 回答
2

因为编译器足够聪明,可以看到

String str2 = "mystring"+9;

是一个常量表达式,因此它在编译时对其进行评估,从而产生一个文字 string "mystring9"

字符串文字存储在一个池中,以便它们可以被重用,这就是为什么str1str2引用同一个String对象(您可以通过将它们与 进行比较来检查==)。

于 2013-10-25T14:19:18.927 回答
2

这是因为编译器可以在编译期间创建字符串 - 即:

"mystring"+9变成"mystring9"

于 2013-10-25T14:19:49.007 回答
2

取决于何时编译代码。

最后一个是在编译时解决的。您还可以再添加一个示例

String str1 = "mystring9";
String str2 = "mystring"+"9";

System.out.println(str1==str2);

你会看到它也会true返回

于 2013-10-25T14:20:29.670 回答
2
String str1 = "mystring9";

执行此行在字符串文字池中创建一个字符串“myString9”以供重用。

根据JLS 第 15.18.1 节String Concatenation Operator +

如果只有一个操作数表达式是字符串类型,则对另一个操作数执行字符串转换(第 5.1.11 节)以在运行时生成字符串。

所以String str2 = "myString"+9导致“myString9”,因此str1并且str2持有对文字池的相同引用并str1==str2给出true.

于 2013-10-25T14:25:32.570 回答
1
String str1 = "mystring9";
String str2 = "mystring"+9;

System.out.println(str1==str2);

那是true 因为它们都在编译时解决了。

顶部的其他两个案例在哪里解决runtime

当我们使用 (+) 运算符连接字符串时,JVM 返回新的StringBuilder(string...).toString()

您在源代码中连接字符串文字时,“在堆内存中创建一个新的字符串实例”是不正确的,

例如,"test" + "test".这种连接是在编译时完成的,就像你写的一样"testtest".

于 2013-10-25T14:18:52.430 回答