Let's consider your first example:
String a="";
for(int i=0;i++<9;)
a+=i;
This code will be executed like this:
String a="";
a=new StringBuilder(a).append(0).toString();
a=new StringBuilder(a).append(1).toString();
a=new StringBuilder(a).append(2).toString();
a=new StringBuilder(a).append(3).toString();
a=new StringBuilder(a).append(4).toString();
a=new StringBuilder(a).append(5).toString();
a=new StringBuilder(a).append(6).toString();
a=new StringBuilder(a).append(7).toString();
a=new StringBuilder(a).append(8).toString();
a=new StringBuilder(a).append(9).toString();
So for each cycle iteration you will have a new StringBuilder
created from the string (every time a new internal char[]
buffer is allocated) which would be converted back to String
every time. On the other hand in the second case you will effectively have
StringBuilder a=new StringBuilder("").append(0).append(1).append(2).append(3)
.append(4).append(5).append(6).append(7).append(8).append(9);
So you will have only one StringBuilder
with only one internal char[]
buffer (it will not be reallocated in your case as all the appendings don't exceed the initial capacity of 16
). So it's simply faster, because you have less objects and nothing is copied multiple times.
Writing a=new String("")
is useless as you will have one more empty string in addition to empty string you already have (which is created and interned during the loading of your class constant pool). Aside from additional empty string (which will become unused after the first loop iteration and garbage collected) it does not differ from the first case.
Please note that it's not specified exactly in JLS how string concatenation is implemented (using implicit StringBuilder
or some other technique), but usually java compilers translate it using StringBuilder
.