/**
* 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
从Java 15开始,StringConcatFactory除了MH_INLINE_SIZED_EXACT之外没有提供其他的连接策略。请参阅邮件列表中的this thread和this bug以了解详细信息。 正如Malt在his answer中指出的,现在只有在编译时禁用invokedynamic才能回到StringBuilder。为此,将-XDstringConcat=inline标志传递给编译器。更多细节请参见上面引用的Malt的答案。 如果使用Maven Central中的JAR文件,you will need to recompile them yourself .
2条答案
按热度按时间rslzwgfq1#
字符串串联功能有两个部分。
1.在运行时
在Java 9+中,在运行时,字符串连接是由
StringConcatFactory
类(javadoc)控制的,这是因为javac
在需要字符串连接的地方生成invokedynamic
字节码到StringConcatFactory::makeConcat
。StringConcatFactory
以Strategy
枚举(源代码)的形式定义了几种运行时连接策略。您可以通过设置
-Djava.lang.invoke.stringConcat
从命令行更改缺省策略要在运行时获得Java-8行为,需要将其设置为
BC_SB
,即“Bytecode,StringBuilder”以下是其他值(为了完整起见):
*编译时
正如Kayaman正确指出的,
StringConcatFactory
只在运行时影响程序。无论字符串连接在哪里,字节码仍然包含invokedynamic
到StringConcatFactory
。有几种方法可以取回对StringBuilder
的调用:--release=8
标志传递给javac,以强制生成与Java-8兼容的代码。-XDstringConcat=inline
来专门控制串联。让我们以这段代码为例:
如果我们编译它而不使用任何标志,我们将得到:
注意
invokedynamic
到makeConcatWithConstants
。然而,如果我们运行
javac -XDstringConcat=inline Print.java
,我们将得到:这里的
String
连接是使用StringBuilder
完成的,就像在Java 8中一样。jei2mxaa2#
从Java 15开始,
StringConcatFactory
除了MH_INLINE_SIZED_EXACT
之外没有提供其他的连接策略。请参阅邮件列表中的this thread和this bug以了解详细信息。正如Malt在his answer中指出的,现在只有在编译时禁用
invokedynamic
才能回到StringBuilder
。为此,将-XDstringConcat=inline
标志传递给编译器。更多细节请参见上面引用的Malt的答案。如果使用Maven Central中的JAR文件,you will need to recompile them yourself .