I believe since Java 9
string concatenation has been implemented using StringConcatFactory
.
Since this is provided as an API in Java how are the methods makeConcat
and makeConcatWithConstants
in StringConcatFactory
used by directly calling the API? I so far could not find any examples of the different ways to use it. Also, what the parameters String name
, MethodType concatType
in makeConcat
and makeConcatWithConstants
and parameters String recipe
, Object... constants
in makeConcatWithConstants
mean and what should be passed to them are not self-evident to me from the Java Docs.
You are not supposed to call this API directly. The class has been designed to provide bootstrap methods for an
invokedynamic
instruction, so its API is straight-forward for that use case, but not for direct invocations.But the documentation is exhaustive:
Emphasis added by me
Note how all parameters are normally provided by the JVM automatically on the basis of the
invokedynamic
bytecode instruction. In this context, it’s a single instruction consuming some arguments and producing aString
, referring to this bootstrap method as the entity knowing how to do the operation.When you want to invoke it manually, for whatever reasons, you’d have to do something like
You could re-use the
MethodHandle
for multiple string concatenations, but your are bound to the parameter types you’ve specified during the bootstrapping.For ordinary string concatenation expressions, each expression gets linked during its bootstrapping to a handle matching the fixed number of subexpressions and their compile-time types.
It’s not easy to imagine a scenario where using the API directly could have a benefit over just writing
arg1 + arg2 + arg3
, etc.The
makeConcatWithConstants
bootstrap method allows to specify constant parts in addition to the potentially changing parameters. For example, when we have the codewe have several constant parts which the compiler can merge to a single string, using the placeholder
\1
to denote the places where the dynamic values have to be inserted, so therecipe
parameter will be"Hello \1, good \1!"
. The other parameter,constants
, will be unused. Then, the correspondinginvokedynamic
instruction only needs to provide the two dynamic values on the operand stack.To make the equivalent manual invocation more interesting we assume the system property
user.name
to be invariant, hence we can provide it as a constant in the bootstrap invocation, use the placeholder\2
to reference it, and produce a handle only consuming one dynamic argument, the time string:Ordinary Java code will rarely make use of the additional
constants
. The only scenario I know of, is the corner case of having\1
or\2
in the original constant strings. To prevent them from being interpreted as placeholders, those substrings will be provided as constants then.As demonstrated in this online code tester, the code
gets compiled to (irrelevant parts omitted):