java字符串连接问题 约定不等于承诺〃 2022-05-28 12:06 162阅读 0赞 ## 前景 ## 在java核心技术 卷1上有这样一段话构建字符串的时候,每次使用+号都会产生一个新的String对象,会浪费资源,最好用StringBuilder。因为那本书的版本是JDK8的,所有这句话是对的,并且网上关于它的讲解也很对,下面附上一个很好的连接 [https://blog.csdn.net/m0\_37589327/article/details/78605268][https_blog.csdn.net_m0_37589327_article_details_78605268] 就JDK 8而言,它的讲解是对的。当+号在不同语句中的时候,每次会new一下,创建新的对象,并且javac会调用StringBuilder。append这个方法进行+的优化。但是当我在JDK9上的时候发现了不同的答案,是JDK9的新特性,下面放上我的实验结果图,与JDK有不同之处 ## 问题 ## 测试代码: public class test { public static void main(String[] args) { String str = ""; long start = System.currentTimeMillis(); for(int i=0; i<100000; i++) str += "a"; long end = System.currentTimeMillis(); System.out.println(end - start); StringBuilder sb = new StringBuilder(); start = System.currentTimeMillis(); for(int i=0; i<100000; i++) sb.append("a"); str = sb.toString(); end = System.currentTimeMillis(); System.out.println(end - start); String a=""; a+="a"; a+="a"; a+="a"; } } 反编译得到的结果 dream@love_lyy:~/java/test/src$ javap -c test.class Compiled from "test.java" public class test { public test(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: ldc #2 // String 2: astore_1 3: invokestatic #3 // Method java/lang/System.currentTimeMillis:()J 6: lstore_2 7: iconst_0 8: istore 4 10: iload 4 12: ldc #4 // int 100000 14: if_icmpge 30 17: aload_1 18: invokedynamic #5, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String; 23: astore_1 24: iinc 4, 1 27: goto 10 30: invokestatic #3 // Method java/lang/System.currentTimeMillis:()J 33: lstore 4 35: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream; 38: lload 4 40: lload_2 41: lsub 42: invokevirtual #7 // Method java/io/PrintStream.println:(J)V 45: new #8 // class java/lang/StringBuilder 48: dup 49: invokespecial #9 // Method java/lang/StringBuilder."<init>":()V 52: astore 6 54: invokestatic #3 // Method java/lang/System.currentTimeMillis:()J 57: lstore_2 58: iconst_0 59: istore 7 61: iload 7 63: ldc #4 // int 100000 65: if_icmpge 82 68: aload 6 70: ldc #10 // String a 72: invokevirtual #11 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 75: pop 76: iinc 7, 1 79: goto 61 82: aload 6 84: invokevirtual #12 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 87: astore_1 88: invokestatic #3 // Method java/lang/System.currentTimeMillis:()J 91: lstore 4 93: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream; 96: lload 4 98: lload_2 99: lsub 100: invokevirtual #7 // Method java/io/PrintStream.println:(J)V 103: ldc #2 // String 105: astore 7 107: aload 7 109: invokedynamic #5, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String; 114: astore 7 116: aload 7 118: invokedynamic #5, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String; 123: astore 7 125: aload 7 127: invokedynamic #5, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String; 132: astore 7 134: aconst_null 135: astore 8 137: aload 8 139: invokedynamic #13, 0 // InvokeDynamic #1:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String; 144: astore 8 146: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream; 149: aload 8 151: invokevirtual #14 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 154: return } ## 理解 ## 由于中文的我没有搜到这个答案,在stackoverflow和jdk9 API上我都看了一下这个函数,先看看API ### API ### ![这里写图片描述][70] API上对这两个方法的描述是:促进了最佳的字符串拼接的方法,能够有效地连接已知数量的、具有已知类型的参数。。。等于没讲。之后看看stackoverflow上怎么讲的。 ### stackoverflow ### 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 } 简而言之,一共提供了6种方法供它来动态选择,至于如何动态选择,我这个新手是搞不懂的了 - -。前5种是SB——StringBuilder,可以看出来的是,并没有舍弃StringBuilder这个方法,而是更加细分了它们,达到一个更好的效果。(纯属个人理解,因为才学java一周。。。)我实现的这个测试代码的结论我觉得暂时是和JDK8测试一致的。 ## 总结 ## 对于我这个新手其实只要知道,JDK9 延续了JDK8的好处,并且还实现了再优化!+号连接字符串,在不同语句中,是会创建新的String对象的,就是多次做了连接,而不是在一句话里面连接好。StringBuilder优就优在这。更深入的学习,对于小白来说,不用知道。等长大了再慢慢学咯~ [https_blog.csdn.net_m0_37589327_article_details_78605268]: https://blog.csdn.net/m0_37589327/article/details/78605268 [70]: /images/20220528/bb7fd7ecceff4c8bbff4c578242f1b5e.png
相关 神秘错误:Java字符串连接问题实例 在Java中,字符串的连接通常是通过`+`操作符或者`String.concat()`方法实现的。然而,有时候可能会遇到一些"神秘错误"。 以下是一个典型的例子: ```j 我就是我/ 2024年09月18日 15:51/ 0 赞/ 1 阅读
相关 Java字符串连接性能优化问题 在Java中,字符串的连接主要通过`+`操作符或`String.concat()`方法实现。对于大规模数据的连接,可能会面临一些性能问题,以下是一些优化建议: 1. **使用 ╰半夏微凉°/ 2024年09月12日 10:03/ 0 赞/ 23 阅读
相关 Java字符串连接操作不当:性能问题 在Java中,字符串连接是通过+或者String的concat()方法实现的。然而,如果处理不当,可能会导致性能问题。以下是一些常见的情况: 1. **频繁拼接大字符串**: 短命女/ 2024年09月06日 06:21/ 0 赞/ 23 阅读
相关 Java字符串连接效率问题探讨 在Java中,字符串的连接主要通过两种方式:拼接操作符+和使用StringBuilder(或StringBuffer)类。 1. **+操作符**: ```java Stri 待我称王封你为后i/ 2024年09月06日 05:48/ 0 赞/ 16 阅读
相关 java 字符串连接 使用“+”连接符让两个字符串进行连接 import java.util.Scanner; import java.util.Arrays; publi ゞ 浴缸里的玫瑰/ 2022年06月17日 22:54/ 0 赞/ 231 阅读
相关 java字符串连接问题 前景 在java核心技术 卷1上有这样一段话构建字符串的时候,每次使用+号都会产生一个新的String对象,会浪费资源,最好用StringBuilder。因为那本书的版本 约定不等于承诺〃/ 2022年05月28日 12:06/ 0 赞/ 163 阅读
相关 java字符串连接 由于String是不可变对象(final),所以,对字符串进行连接、替换操作时,String对象总是会生成新的对象。所以连接和替换时性能很差。 String常量字符串的累加 谁践踏了优雅/ 2022年05月14日 12:43/ 0 赞/ 232 阅读
相关 Java连接字符串 对于已经定义的字符串,可以对其进行各种操作。连接多个字符串是字符串操作中最简单的一种。通过字符串连接,可以将两个或多个字符串、字符、整数和浮点数等类型的数据连成一个更大的字符串 以你之姓@/ 2021年12月14日 18:51/ 0 赞/ 311 阅读
相关 字符串头尾连接问题-木棒连接 问题 D: 木棒连接 时间限制: 1 Sec 内存限制: 64 MB 提交: 996 解决: 51 \[ [提交][Link 1]\]\[ [状态][Li 悠悠/ 2021年12月10日 16:23/ 0 赞/ 215 阅读
还没有评论,来说两句吧...