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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/693597/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 18:25:32  来源:igfitidea点击:

Is there a difference between String concat and the + operator in Java?

javastring

提问by Vasil

Duplicate

复制

java String concatenation

java字符串连接

I'm curious what is the difference between the two.

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

The way I understand the string pool is this:

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

This creates 3 string objects in the string pool, for 2 of those all references are lost.

这会在字符串池中创建 3 个字符串对象,因为其中 2 个所有引用都丢失了。

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

Doesn't this also create 3 objects in the string pool?

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

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

I know StringBuilder and StringBuffer are much more efficient in terms of memory usage when there's lots of concatination to be done. I'm just curious if there's any difference between the + operator and concat in terms of memory usage.

我知道 StringBuilder 和 StringBuffer 在需要完成大量连接时在内存使用方面效率更高。我只是好奇 + 运算符和 concat 在内存使用方面是否有任何区别。

回答by brian-brazil

Unless the argument to concat is an empty string, then

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

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

will also create 3 strings.

还将创建 3 个字符串。

More info: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html

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

回答by John Feminella

There's no difference in this particular case; however, they're not the same in general.

在这种特殊情况下没有区别;然而,它们总体上并不相同。

str1 += str2is equivalent to doing the following:

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

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

To prove this to yourself, just make a simple method that takes two strings and +='s the first string to the second, then examine the disassembled bytecode.

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

By contrast, str1.concat(str2)simply makes a new string that's the concatenation of str1and str2, which is less expensive for a small number of concatenated strings (but will lose to the first approach with a larger number).

相比之下,str1.concat(str2)简单地创建一个新的字符串,它是str1and的串联str2,这对于少量串联的字符串来说成本较低(但会输给具有较大数量的第一种方法)。

Additionally, if str1is null, notice that str1.concat(str2)throws a NPE, but str1 += str2will simply treat str1as if it were null without throwing an exception. (That is, it yields "null" concatenated with the value of str2. If str2were, say, "foo", you would wind up with "nullfoo".)

此外,如果str1为 null,请注意str1.concat(str2)抛出 NPE,但str1 += str2会简单地将其str1视为 null 而不抛出异常。(也就是说,它产生与 的值连接的“null” str2。如果str2是,比如说“foo”,你会得到“nullfoo”。)



Update:See this StackOverflow question, which is almost identical.

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

回答by Michael Borgwardt

The way I understand the string pool is this:

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

You seem to have a misconception concerning that term. There is no such thing as a "string pool" - the way you're using it, it looks like you just mean all String object on the heap. There isa runtime constant poolwhich contains, among many other things, compile-time String constants and String instances returned from String.intern()

你似乎对这个词有误解。没有像“字符串池”这样的东西——你使用它的方式,看起来你只是指堆上的所有 String 对象。这里一个运行常量池包含,在许多其他事情,编译时字符串常量,并从返回的字符串实例String.intern()

回答by Alan Moore

The important difference between +=and concat()is not performance, it's semantics. concat()will only accept a string argument, but +(or +=) will accept anything. If the non-string operand is an object, it will be converted to a string by calling toString()on it; a primitive will be converted as if by calling the appropriate method in the associated wrapper class, e.g., Integer.toString(theInt); and a null reference becomes the string "null".

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

Actually, I don't know why concat()even exists. People see it listed in the API docs and assume it's there for a good reason--performance being the most obvious reason. But that's a red herring; if performance is really a concern, you should be using a StringBuilder, as discussed in the thread John linked to. Otherwise, +or +=is much more convenient.

其实我也不知道为什么concat()会存在。人们看到它列在 API 文档中并认为它存在是有充分理由的——性能是最明显的原因。但这是一个红鲱鱼;如果性能确实是一个问题,那么您应该使用 StringBuilder,如 John 链接到的线程中所述。否则,+还是+=方便很多。

EDIT: As for the issue of "creating objects in the string pool," I think you're misunderstanding what the string pool is. At run-time, the actual character sequences, "str" and "end" will be stored in a dedicated data structure, and wherever you see the literals "str"and "end"in the source code, the bytecode will really contain references to the appropriate entries in that data structure.

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

In fact, the string pool is populated when the classes are loaded, not when the code containing the string literals is run. That means each of your snippets only creates one object: the result of the concatenation. (There's also some object creation behind the scenes, which is a little different for each of the techniques, but the performance impact is not worth worrying about.)

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