tags:

views:

1797

answers:

4

Duplicate

java String concatenation

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.

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

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

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.

A: 

Unless the argument to concat is an empty string, then

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

will also create 3 strings.

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

Two of them are created by loading the code, not by executing it. += uses a StringBuilder.
Tom Hawtin - tackline
+10  A: 

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

str1 += str2 is equivalent to doing the following:

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 str1 and str2, which is less expensive for a small number of concatenated strings (but will lose to the first approach with a larger number).

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


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

John Feminella
concat is less expensive. For proof, read the JLS rather than hack about drawing fallacies.
Tom Hawtin - tackline
@Tom: Thanks for the feedback. concat() is only less expensive for small numbers of strings. StringBuilder wins with larger N. I clarified my answer to make this more clear.
John Feminella
Your last example is incorrect, the addition would result in "nullstr2" (if the value of str2 was "str2" of course)The concat does indeed result in NPE.
Jorn
@Jorn: Ugh. I meant to say that "str1 will be treated as if it were null". Not sure how my fingers typed what actually went up there. Thanks for the catch.
John Feminella
+1  A: 

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 is a runtime constant pool which contains, among many other things, compile-time String constants and String instances returned from String.intern()

Michael Borgwardt
+2  A: 

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".

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.

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.

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.)

Alan Moore