具有相同引用的字符串连接?

String Concat With Same Reference?

这是我的代码,我现在对字符串池和 此输出的堆存储。

public class String1 {
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        String str = "abcd";
        String str1 = "" ;

        str1=str1+"abcd";

        if(str.equals(str1))
            System.out.println("True");
        else
            System.out.println("False");

        if(str == str1)
            System.out.println("True");
        else
            System.out.println("False");
    }
}

现在,我正在创建字符串 str 并将存储在字符串池中(如果我弄错了请纠正我!)。 现在,在使用字符串 "abcd" 连接 str1 之后,它们都具有相同的值。 所以,我认为 str 和 str1 应该在字符串池中有相同的引用,所以,第二个 if 语句应该打印 true 但它打印 false.

所以,我的问题是为什么 str 和 str1 没有得到相同的引用?

Java automatically interns (意思是,把他们放到String池中)String literals,不是新创建的Strings。另见 .

请记住,字符串是不可变的,因此 + 运算符必须创建一个新字符串 - 它不能附加到现有字符串。在内部,+ 运算符使用 StringBuilder 来连接字符串。最终结果通过 StringBuilder.toString() 检索,本质上是 return new String(value, 0, count);.

这个新创建的String不会自动放入String池中。

因此 str1 引用与 str 不同,即使字符串具有相同的内容。 str指向字符串池中的一个位置,而str1指向堆中的一个位置。

如果你添加

str1 = str1.intern();

str1 = str1 + "abcd"; 显式实习新创建的字符串之后,您的第二个 if 语句 returns true.

或者,str1 = (str1 + "abcd").intern(); 会产生相同的效果。

您说得对,字符串已添加到字符串池中。但是 == 检查两个对象是否指向字符串池中的相同引用(以使其更简单地指向相同的内存位置)。而 .equals() 方法检查两个对象的值是否相同。

如果是字符串比较值,我们应该使用 equals 方法,因为它比较字符串变量中存在的值。

但是当我们选择使用 == 比较字符串变量时,它比较的是 String 对象的地址而不是值,因此即使它们具有相同的值,它也会 return false。