使用 + 运算符连接两个字符串时未创建引用
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.concat
,javadoc 指出:
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 极客的问答节目。
我正在尝试连接两个字符串,一个字符串有一些值,另一个字符串为空。
示例:
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.concat
,javadoc 指出:
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 极客的问答节目。