据我所知,我们不能使用 == 运算符来比较 Java 中的 String 值。所以我写了下面的代码:
public class Test {
public static void main(String[] args) {
String s1 = "My Computer";
String s2 = "My" + " Computer";
System.out.println(s1 == s2);
}
}
我期望的结果是false,因为这是分配了不同存储位置的两个不同对象(如果我错了,请对此进行纠正)。但是当我执行代码时,输出为true。
然后,将s2的值更改为:
我期望的结果是 false ,因为这是分配了不同存储位置的两个不同对象(如果我错了,请对此进行纠正)。但是当我执行代码时,输出为 true 。
然后,将 s2 的值更改为:
String str = "My";
String s2 = str + " Computer"; //instead of "My" + " Computer"
然后,当我执行代码时,输出为 false 。
现在,尽管我在两个语句中都使用了 + (不是 concat() 方法),但我无法理解这两个语句的区别。任何人都可以解释。
最佳答案
除非表达式为常量表达式,否则将重新创建String对象(第12.5节)。
因此,当您将一个字符串常量连接到另一个字符串常量时,该字符串常量将视为一个常量表达式,因此将在编译时进行评估,并替换为字符串常量“My Computer”。
您可以通过在已编译的类上运行 javap -c 来验证这一点。
public class Test {
public static void main(String[] args) {
String s1 = "My Computer";
String s2 = "My" + " Computer";
String s3 = "My";
String s4 = s3 + " Computer";
System.out.println(s1 == s2); //true
System.out.println(s1 == s4); //false
}
}
如您所见,前两个赋值( s1 和 s2 )加载完全相同的常量( #2 ),因此使用相同的对象。而对 s4 的赋值未定义为constant expression(即使足够聪明的编译器可以弄清楚,也不允许这样做),因此您得到了全部“创建一个StringBuilder,将字符串附加到其上” ,将结果转换为新的字符串”过程。
另外,如果在上面的代码中将 final 修饰符添加到 s3 ,则会使 s3 + ” Computer” 再次成为常量表达式,并且两个比较都将显示 true 。