3

Below is code snippet in instance method

 String x = new StringBuffer().append("a").append("b").append("c").toString()

i am under impression , first new stringbuffer is created, then a is appended atlast of string buffer, similarly b and c. After that stringbuffer is converted to string. So as per me 2 objects are created(one for string buffer and another for string). correct? Basically as per me no intermediate objects will be created for String "a","b","c". Is this right?

Edit:- as per all of the replies, looks like objects will be created for string literals "a","b","c" But if i go by link http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/StringBuffer.html#toString(), this should not create temporary strings. Search "Overall, this avoids creating many temporary strings." on this link. Agreed it is for 1.4.2 but i hope fundamental remain same for 1.6

Yes if i do below instead of above five objects will be created. three for "a","b","c" . one for string buffer. Then at last for string converted from stringbuffer. objects for "a","b","c" and lastly string "abc" will go too pool and be there in for life time

String str1="a";
String str2="b";
String str3="c";
String x = new StringBuffer().append(str1).append(str2).append(str3).toString()

Is above understanding correct?

M Sach
  • 33,416
  • 76
  • 221
  • 314
  • related: http://stackoverflow.com/questions/3297867/difference-between-string-object-and-string-literal – leonbloy Jul 26 '12 at 16:21

3 Answers3

3

There is no difference between your first and second snippet in terms of how many objects are created. Strings "a", "b", and "c" will participate in the process, although their interned copies may be used. In the absence of further references to str1..str3, the compiler is free to transform your second snippet into your first one, eliminating the variables.

In addition, there may be an internal reallocation inside StringBuffer's append, if the memory in its internal string is insufficient to hold the data being appended. This is only a theoretical possibility, but it is there.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • so even for the first code snippet, objects will be created for "a","b" and "c" and they will go to string pool right? – M Sach Jul 26 '12 at 16:27
  • @MSach Right, the objects may or may not be created during this particular call, but they will participate as objects either way. – Sergey Kalinichenko Jul 26 '12 at 16:32
  • But as per link http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/StringBuffer.html#toString(), this should not create temporary strings. Search "Overall, this avoids creating many temporary strings." on this link – M Sach Jul 26 '12 at 16:33
  • 1
    @MSach The paragraph that you are quoting refers to an alternative of doing concatenation by creating temporary objects for intermediate results, such as `"ab"`. In this example, temporary `String("ab")` is never created, but the parts from which the final string is composed are created in both scenarios. – Sergey Kalinichenko Jul 26 '12 at 16:36
  • Thanks dasblinkenlight got it. Thats why i love this forum. Probably you can not discuss these kind of issues anywhere – M Sach Jul 26 '12 at 16:54
1

As pointed out in other answers, your two snippets are equivalent (regarding String object creation). The would be different instead if the second snippet were written as:

String str1= new String("a");
...

Only in this case you are guaranteed to have a new String object instantiated (not that you'd normally want that). See also here.

Community
  • 1
  • 1
leonbloy
  • 73,180
  • 20
  • 142
  • 190
1

The strings "a", "b", "c" are literals in both your code snippets. They will be created by the class loader before your code can execute, and there is no way (and normally also no point) to avoid that.

So both code snippets essentially do the same and they both create the same number of objects.

And, BTW neither of the snippets is valid code - you can not assign StringBuffer = String as you do in the last statement in both snippets.

EDIT: You also ask about Java versions >1.4. From Java5 up, StringBuffer should be replaced with StringBuilder (it does essentially exactly the same, but it is not synchronized, thus it performs a little better).

Durandal
  • 19,919
  • 4
  • 36
  • 70
  • Thanks i have corrected it. But as per link http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/StringBuffer.html#toString(), this should not create temporary strings. Search "Overall, this avoids creating many temporary strings." on this link – M Sach Jul 26 '12 at 16:35
  • The Javadoc is correct, of course, but its not relevant for literals. When you use a literal (basically a string dirctly embedded in the source with quotes around it - like "a") the literal is turned into a string object when the class is loaded. That string object (representing the literal) then exists until there are no more references to it (at last until the class using it is unloaded). – Durandal Jul 26 '12 at 16:42