String concat和Java中的+运算符有区别吗?

重复

java字符串连接

我很好奇两者之间有什么区别。

我理解字符串池的方式是这样的:

这会在字符串池中创建3个字符串对象,其中2个字符串对象将丢失。

String mystr = "str"; mystr += "end"; 

这不会在字符串池中创建3个对象吗?

 String mystr = "str"; mystr = mystr.concat("end") 

我知道StringBuilder和StringBuffer在内存使用方面更有效率,因为需要进行大量的连接。 我只是好奇,如果在内存使用方面+运算符和concat之间有任何区别。

这种特殊情况没有区别; 但是,它们一般不一样。

str1 += str2相当于执行以下操作:

 str1 = new StringBuilder().append(str1).append(str2).toString(); 

为了向自己certificate这一点,只需创建一个简单的方法,它接受两个字符串, += ‘s第一个字符串到第二个字符串,然后检查反汇编的字节码。

相比之下, str1.concat(str2)只是创建一个新的字符串,它是str1str2的串联,对于少量连接的字符串来说,它的成本较低(但是对于第一种方法,它会输入更大的数字)。

另外,如果str1为null,请注意str1.concat(str2)抛出一个NPE,但str1 += str2只会将str1视为null而不抛出exception。 (也就是说,它产生的“null”与str2的值连接。如果str2是,例如“foo”,你最终会得到“nullfoo”。)


更新:请参阅此StackOverflow问题 ,这几乎完全相同。

+=concat()之间的重要区别不是性能,而是语义。 concat()只接受字符串参数,但+ (或+= )将接受任何内容 。 如果非字符串操作数是一个对象,则通过调用toString()将其转换为字符串; 一个原语将被转换,好像通过调用相关包装类中的适当方法,例如Integer.toString(theInt) ; 并且空引用变为字符串"null"

实际上,我不知道为什么concat()甚至存在。 人们看到它在API文档中列出并假设它存在的原因很充分 – 性能是最明显的原因。 但那是一个红鲱鱼; 如果性能确实是一个问题,你应该使用StringBuilder,如John链接的线程中所讨论的那样。 否则, ++=更方便。

编辑:至于“在字符串池中创建对象”的问题,我认为你误解了字符串池是什么。 在运行时,实际的字符序列“str”和“end”将存储在专用的数据结构中,无论你在源代码中看到文字"str""end" ,字节码都会真正包含引用到该数据结构中的相应条目。

实际上,在加载类时填充字符串池,而不是在运行包含字符串文字的代码时填充。 这意味着每个片段只创建一个对象:连接的结果。 (幕后还有一些对象创建,每种技术都有一些不同,但性能影响不值得担心。)

除非concat的参数是空字符串,否则

 String mystr = "str"; mystr = mystr.concat("end") 

还将创建3个字符串。

更多信息: http : //java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html

我理解字符串池的方式是这样的:

你似乎对这个词有误解。 没有“字符串池”这样的东西 – 你使用它的方式,看起来你只是意味着堆上的所有String对象。 有一个运行时常量池 ,其中包含编译时字符串常量和从String.intern()返回的String实例。