Java 8 introduced String Deduplication that can be enabled by launching JVM with -XX:+UseStringDeduplication option allowing to save some memory by referencing
I absolutely understand that this does not answer the question, just wanted to mention that jdk-9 introduces one more optimization that is on by default called :
-XX:+CompactStrings
where Latin1 characters occupy a single byte instead of two (via a char). Because of that change many internal methods of String have changed - they act the same to the user, but internally they are faster in a lot of cases.
Also in case of Strings for concatenating two Strings together via the plus sign the javac is going to generate different bytecode.
There is no bytecode instruction that concatenates two Strings together so the javac would generate a
StringBuilder#append
in the back-end. Until jdk-9.
Now the bytecode delegates to
StringConcatFactory#makeConcatWithConstants
or
StringConcatFactory#makeConcat
via the invokedynamic bytecode instruction:
aload_0
1: aload_2
2: aload_1
3: invokedynamic #8, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
8: areturn
How the two strings are concatenated is a Runtime decision now. it could be still a StringBuilder or it could be a concatenation of byte arrays, etc. All you know that this can change and you will get the fastest possible solution.
EDIT
I've just debugged and saw that there are quite a lot of strategies on how to append these Strings:
private enum Strategy {
/**
* Bytecode generator, calling into {@link java.lang.StringBuilder}.
*/
BC_SB,
/**
* Bytecode generator, calling into {@link java.lang.StringBuilder};
* but trying to estimate the required storage.
*/
BC_SB_SIZED,
/**
* Bytecode generator, calling into {@link java.lang.StringBuilder};
* but computing the required storage exactly.
*/
BC_SB_SIZED_EXACT,
/**
* MethodHandle-based generator, that in the end calls into {@link java.lang.StringBuilder}.
* This strategy also tries to estimate the required storage.
*/
MH_SB_SIZED,
/**
* MethodHandle-based generator, that in the end calls into {@link java.lang.StringBuilder}.
* This strategy also estimate the required storage exactly.
*/
MH_SB_SIZED_EXACT,
/**
* MethodHandle-based generator, that constructs its own byte[] array from
* the arguments. It computes the required storage exactly.
*/
MH_INLINE_SIZED_EXACT
}
The default being:
MH_INLINE_SIZED_EXACT