我很好奇两者之间有什么区别.
我理解字符串池的方式是这样的:
这会在字符串池中创建3个字符串对象,其中2个字符串对象将丢失.
String mystr = "str";
mystr += "end";
Run Code Online (Sandbox Code Playgroud)
这不会在字符串池中创建3个对象吗?
String mystr = "str";
mystr = mystr.concat("end")
Run Code Online (Sandbox Code Playgroud)
我知道StringBuilder和StringBuffer在内存使用方面更有效率,因为要进行大量的连接.我只是好奇,如果在内存使用方面+运算符和concat之间有任何区别.
Joh*_*lla 30
这种特殊情况没有区别; 但是,它们总的来说并不相同.
str1 += str2 相当于执行以下操作:
str1 = new StringBuilder().append(str1).append(str2).toString();
Run Code Online (Sandbox Code Playgroud)
为了向自己证明这一点,只需创建一个简单的方法,它接受两个字符串,+=第一个字符串到第二个字符串,然后检查反汇编的字节码.
相比之下,str1.concat(str2)只是使一个新的字符串,是的串联str1和str2,这是少数连接的字符串的更便宜(但会失去第一种方法具有更大的数字).
另外,如果str1为null,请注意str1.concat(str2)抛出NPE,但str1 += str2只会将其str1视为null而不抛出异常.(也就是说,它产生的"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")
Run Code Online (Sandbox Code Playgroud)
还将创建 3 个字符串。
更多信息: https: //docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html。