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)
只是创建一个新的字符串,它是str1
和str2
的串联,对于少量连接的字符串来说,它的成本较低(但是对于第一种方法,它会输入更大的数字)。
另外,如果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实例。