使用 + 运算符连接两个字符串时未创建引用

Reference is not created while using + operator to concat two strings

我正在尝试连接两个字符串,一个字符串有一些值,另一个字符串为空。

示例:

String string1="Great"
String string2="";

并用 concat 函数和 + 运算符连接这两个字符串

示例:

 String cat=string1.concat(string2)
 String operator=string1+string2

据我了解,在 concat 函数中使用空字符串时,由于 string2 为空,因此不会创建新的引用。但是在使用 + 运算符时,将在字符串池常量中创建一个新引用。但是在下面的代码中,当使用 + 运算符时,不会创建新引用。

public class Main {
    
    public static void main(String[] args) {
        String string1="Great",string2="";

        String cat=string1.concat(string2);
        if(string1==cat)
        {
            System.out.println("Same");
        }
        else
        {
            System.out.println("Not same");
        }
        String operator=string1+string2;
        if(operator==string1)
            System.out.println("Same");
        else
            System.out.println("Not same");
    }
}

输出:

字符串 1 :69066349

目录:69066349

相同

字符串 1 :69066349

接线员:69066349

不一样


从上面的代码来看,因为它使用了 + 操作符,所以变量的引用 : 操作符应该引用新的内存,但它指向的是 string1 引用。请解释以上代码。

文档里都有。

对于 String.concatjavadoc 指出:

If the length of the argument string is 0, then this String object is returned.

对于 + 运算符,JLS 15.8.1 表示:

The result of string concatenation is a reference to a String object that is the concatenation of the two operand strings. The characters of the left-hand operand precede the characters of the right-hand operand in the newly created string.

The String object is newly created (§12.5) unless the expression is a constant expression (§15.29).

如您所见,对于第二个字符串的长度为零并且这不是常量表达式的情况,结果会有所不同。

这就是您的示例中发生的情况。


你还说:

But while using + operator a new reference will be created in the string pool constant.

这与您的问题没有直接关系,但是...实际上,不会在那里创建它。它将在堆中创建对常规(非实习)String 对象的引用。 (它只会在 class 文件的常量池中……因此在字符串池中……如果它是一个 常量表达式;参见 JLS 15.29

注意字符串池和class文件常量池是不同的东西。


我可以添加一些东西吗:

  • 您可能不应该使用 String.concat+ 运算符更简洁,JIT 编译器应该知道如何优化不必要的中间字符串的创建......在少数情况下,您可能出于性能原因考虑使用 concat

  • 利用没有创建新对象的事实是一个坏主意,这样您就可以使用==而不是[=21] =].您的代码将很脆弱。只需始终使用 equals 来比较 String 和原始包装器类型。更简单更安全。

简而言之,您甚至问这个问题 表明 您正在走入死胡同。了解 concat+ 之间的这种边缘情况差异是......毫无意义......除非你打算参加 Java 极客的问答节目。