我绝对理解这并没有回答这个问题,只是想提一下jdk-9引入了另一个优化,默认情况下称为:
-XX:+紧凑型字符串
其中 Latin1 字符占用单个字节而不是两个字节(通过字符)。由于这种变化,String的许多内部方法都发生了变化 - 它们对用户的作用相同,但在很多情况下,它们在内部速度更快。
此外,如果字符串通过加号将两个字符串连接在一起,javac将生成不同的字节码。
没有字节码指令将两个字符串连接在一起,因此javac将生成一个
StringBuilder#append
在后端。直到jdk-9。
现在字节码委托给
StringConcatFactory#makeConcatWithConstants
或
StringConcatFactory#makeConcat
通过调用动态字节码指令:
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
现在,这两个字符串的串联方式是运行时的决定。它可能仍然是一个StringBuilder,或者它可能是字节数组的串联,等等。您所知道的是,这种情况可能会改变,您将获得最快的解决方案。
编辑
我刚刚调试过,发现有很多关于如何附加这些字符串的策略:
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
}
默认值为:
MH_INLINE_SIZED_EXACT