当前位置: 首页 > 后端技术 > Java

Java代码中的字符串拼接方式分析

时间:2023-04-01 14:36:48 Java

本文讨论了以下四种字符串拼接方式:“+”、StringBuilder、StringJoiner、String#join,对比分析和最佳实践讨论。结论后面的内容比较无聊,先说结论吧:本文讨论的字符串拼接方式有:“+”、StringBuilder、StringJoiner、String#join。在简单的字符串拼接场景下,如:“a”+“b”+“c”,以上四种方法在性能上没有明显差异。在循环字符串拼接的场景下,使用“+”号性能是最低的,其他三种方法性能没有明显差异,但是根据验证结果可以发现指定初始容量的StringBuilder效率最高,当然不仅仅是性能,还要考虑垃圾回收效率,避免OOM,本文最后对StringBuffer进行了补充对比,在没有争用共享资源的场景下,StringBuffer的性能并没有明显下降。最佳实践阿里巴巴Java开发手册-日志协议“5”可以优化:占位符的使用可读性差,不方便,Lambda可以考虑延迟字符串的拼接,使用起来更方便。阿里巴巴Java开发手册-OOP协议《23》可优化:拼接循环时必须使用StringBuilder;拼接大量大容量字符串时,尽量使用StringBuilder指定初始容量。简单的字符串拼接可以用任何方式完成,建议直接使用“+”号以获得最佳可读性。尽量使用JDK直接提供的特性,比如“+”拼接字符串、Synchronized关键字等,因为编译器+JVM会不断优化这个,JDK升级可以获得更大的收益。除非有明确的理由要自己实现类似的功能。在需要考虑线程安全的场景下,可以考虑使用StringBuffer进行字符串拼接,但是一般来说没有这个需求,所以不应该使用StringBuffer,以免增加复杂度。分析过程环境系统:windows1021H1JDK:OpenJDK1.8.0_302分析示例代码:@Slf4jpublicclassStringConcat{@SneakyThrowspublicstaticvoidmain(String[]args){log.info("java虚拟机warm-upstarts");字符串[]strs=新字符串[6000000];对于(inti=0;i()VALOAD0INVOKEVIRTUALjava/lang/StringBuilder.append(Ljava/lang/字符串;)Ljava/lang/StringBuilder;LDC"+"INVOKEVIRTUALjava/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;ALOAD1INVOKEVIRTUALjava/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;LDC"+"INVOKEVIRTUALjava/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;ALOAD2INVOKEVIRTUALjava/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringB上级;INVOKEVIRTUALjava/lang/StringBuilder.toString()Ljava/lang/String;ARETURNL1LOCALVARIABLE一个Ljava/lang/String;L0L10LOCALVARIABLEbLjava/lang/String;L0L11LOCALVARIABLEcLjava/lang/String;L0L12MAXSTACK=2MAXLOCALS=3//访问标志0xAprivatestaticsimpleStringBuilder(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;//参数a//参数b//参数cL0LINENUMBER129L0NEWjava/lang/StringBuilderDUPINVOKESPECIALjava/lang/StringBuilder.()VASTORE3L1LINENUMBER130L1ALOAD3ALOAD0INVOKEVIRTUALjava/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;POPL2LINENUMBER131L2ALOAD3LDC"+"INVOKEVIRTUALjava/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;POPL3LINENUMBER132L3ALOAD3ALOAD1INVOKEVIRTUALjava/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;POPL4LINENUMBER133L4ALOAD3LDC"+"INVOKEVIRTUALjava/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;POPL5LINENUMBER134L5ALOAD3ALOAD2INVOKEVIRTUALjava/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;POPL6LINENUMBER135L6ALOAD3INVOKEVIRTUALjava/lang/StringBuilder.toString()Ljava/lang/String;ARETURNL7LOCALVARIABLE一个Ljava/lang/String;L0L70LOCALVARIABLEbLjava/lang/String;L0L71LOCALVARIABLEcLjava/lang/String;L0L72LOCALVARIABLE构建器Ljava/lang/StringBuilder;L1L73最大堆叠=2最大局部=4