The statement, in this exact form, is just wrong, and it fits into the picture that the linked blog continues to write nonsense, like that you had to wrap references with Objects.toString(…)
to handle null
, e.g. "att1='" + Objects.toString(att1) + '\''
instead of just "att1='" + att1 + '\''
. There is no need to do that and apparently, the author did never re-check these claims.
The JVM is not responsible for compiling the +
operator, as this operator is merely a source code artifact. It’s the compiler, e.g. javac
which is responsible, and while there is no guaranty about the compiled form, compilers are encouraged to use a builder by the Java Language Specification:
An implementation may choose to perform conversion and concatenation in one step to avoid creating and then discarding an intermediate String object. To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression.
Note that even if a compiler does not perform this optimization, there still is no such thing as a +
operator on the byte code level, so the compiler has to pick an operation, a JVM understands, e.g. using String.concat
, which might be even faster than using a StringBuilder
in the case you’re just concatenating exactly two strings.
Even assuming the worst compilation strategy for string concatenation (still being within the specification), it would be wrong to say to never concatenate strings with +
, as when you are defining compile time constants, using +
is the only choice, and, of course, a compile-time constant is usually more efficient than using a StringBuilder
at runtime.
In practice, the +
operator applied to non constant strings was compiled to a StringBuffer
usage before Java 5 and to a StringBuilder
usage in Java 5 to Java 8. When the compiled code is identical to the manual usage of StringBuffer
resp. StringBuilder
, there can’t be a performance difference.
The transition to Java 5, more than a decade ago, was the first time, where string concatenation via +
had a clear win over manual StringBuffer
use, as simply recompiling the concatenation code made it use the potentially faster StringBuilder
internally, while the code manually dealing with StringBuffer
needed to be rewritten to use StringBuilder
, which had been introduced in that version.
Likewise, Java 9 is going to compile the string concatenation using an invokedynamic
instruction allowing the JRE to bind it to actual code doing the operation, including optimizations not possible in ordinary Java code. So only recompiling the string concatenation code is needed to get this feature, while there is no equivalent manual usage for it.
That said, while the premise is wrong, i.e. string concatenation never was considered evil, the advice is correct, do not hesitate to use it.
There are only a few cases where you really might improve performance by dealing with a buffer manually, i.e. when you need a large initial capacity or concatenate a lot within loops and that code has been identified as an actual performance bottleneck by a profiling tool…