makeConcat()
and makeConcatWithConstants()
, 哪个是StringConcatFactory
API入口点,都使用doStringConcat()
,这会产生一个CallSite
所使用的invokedynamic
.
doStringConcat()
calls generate(Lookup, String, MethodType, Recipe)
其中包含您所询问的枚举的以下开关:
switch (STRATEGY) {
case BC_SB:
return StringConcatFactory.BytecodeStringBuilderStrategy.generate(lookup, className, mt, recipe, StringConcatFactory.Mode.DEFAULT);
case BC_SB_SIZED:
return StringConcatFactory.BytecodeStringBuilderStrategy.generate(lookup, className, mt, recipe, StringConcatFactory.Mode.SIZED);
case BC_SB_SIZED_EXACT:
return StringConcatFactory.BytecodeStringBuilderStrategy.generate(lookup, className, mt, recipe, StringConcatFactory.Mode.SIZED_EXACT);
case MH_SB_SIZED:
return StringConcatFactory.MethodHandleStringBuilderStrategy.generate(mt, recipe, StringConcatFactory.Mode.SIZED);
case MH_SB_SIZED_EXACT:
return StringConcatFactory.MethodHandleStringBuilderStrategy.generate(mt, recipe, StringConcatFactory.Mode.SIZED_EXACT);
case MH_INLINE_SIZED_EXACT:
return StringConcatFactory.MethodHandleInlineCopyStrategy.generate(mt, recipe);
default:
throw new StringConcatException("Concatenation strategy " + STRATEGY + " is not implemented");
}
-
BytecodeStringBuilderStrategy
把手BC_SB
, BC_SB_SIZED
and BC_SB_SIZED_EXACT
。它生成相同的StringBuilder
- 使用字节码javac
如果您只是在 Java 代码中编写串联,则会生成。主要区别在于该字节码是在运行时(而不是编译时)生成并使用Unsafe.defineAnonymousClass()
.
-
MethodHandleStringBuilderStrategy
把手MH_SB_SIZED
and MH_SB_SIZED_EXACT
。它用MethodHandle
机械(包括MethodHandle
组合)在其之上构建相同的串联链StringBuilder
来电。它不使用任何私有 API(例如Unsafe
),所以它可能是最不可移植的策略。
-
MethodHandleInlineCopyStrategy
把手MH_INLINE_SIZED_EXACT
。它还使用MethodHandle
建立串联链的机械MethodHandle
组成,但不是StringBuffer
它直接使用字节数组,尽可能避免复制。为此,它使用了一些内部 API 和一些有关 JDK 实现细节的知识(例如String
避免复制字符串字节的构造函数)。所以这个实现更加脆弱(对于 JDK 的更改),但它也允许更快的速度。
一点总结
我们可以看出,三者有两点不同:a)使用什么作为缓冲区来构建字符串以及b)串联链是如何创建的。
-
BytecodeStringBuilderStrategy
(BC_SB_xxx
) uses StringBuilder
和运行时代码生成。
-
MethodHandleStringBuilderStrategy
(MH_SB_xxx
) uses StringBuilder
and MethodHandle
s
-
MethodHandleInlineCopyStrategy
(MH_INLINE_SIZED_EXACT
) 使用字节数组并且MethodHandle
s.