开发者

Java中字符串String的+和+=及循环操作String原理详解

String对象android是不可变的:意思就是无论是对String的新增或修改,出现一个全新的String内容时,都意味着诞生了一个新的对象。但是如果内容不变的话,增加的只是对象的引用而已。

例如:

String a = "ljh";
String b = "ljh";
String c = "ljh";

System.out.println(a==b);
System.out.println(b==c);

结果都是true

但是这种不可变性会产生一些性能上的问题,所以JVM对String对象重载“+”“+=”进行了一些优化

操作符“+”可以用来连接String

String aaa = "ljh";
String bbb = "big";
String ccc = aaa+bbb+"aaaa";

在jdk8中,上述代码中在底层其实是编译器擅自调用了StringBuilder类进行+的操作,主要原因是StringBuilder的append()更加高效,我们来看一下字节码。

  public static void main(Java.lang.String[]);
    Code:
       0: ldc           #2                  // String ljh
       2: astore_1
       3: ldc           #3                  // String big
       5: astore_2
       6: new           #4                  // class java/lang/StringBuilder
       9: dup
      10: invokespecial #5                  // Method java/lang/StringBuilder."<init>":()V
      13: aload_1
      14: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      17: aload_2
      18: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      21: ldc           #7                  // String aaaajs
      23: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      26: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      29: astore_3
      30: return

可以看出一共有四个对象,分别是三个String 和一个StringBuilder

我们再来看一下+=

String a = "aaa";
a += "bbb";

字节码如下

    Code:

       0: ldc           #2                  // String aaa

       2: astore_1

       3: new           #3                  // class java/lang/StringBuilder

       6: dup

       7: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V

      10: aload_1

     开发者_JS学习; 11: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

      14: ldc           #6                  // String bbb

      16: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

      19: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;

      22: astore_1

      23: return

可以看出先创建了一个“aaa”字符串,然后当a遇到+=时,创建了一个StringBuilder对象,并append了aaa字符串。之后创建了一个“bbb”对象,然后append了bbb字符串,最后调用StringBuilder的toString方法。

接下来再看看循环中调用+=会是什么样子

String a = "aaa";
a += "bbb";
for(int i=0;i<5;i++){
    a+="ccc";
}

    Code:

       0: ldc           #2       &nb编程sp;          // String aaa

       2: astore_1

       3: new           #3                  // class java/lang/StringBuilder

       6: dup

       7: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V

      10: aload_1

      11: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

      14: ldc           #6                  // String bbb

      16: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

      19: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;

      22: astore_1

      23: iconst_0

      24: istore_2

      25: iload_2

      26: iconst_5

      27: if_icmpge     56

      30: new           #3                  // class java/lang/StringBuilder

      33: dup

      34: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V

      37: aload_1

      38: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

      41: ldc           #8                  // String ccc

      43: invokevirtual #5               &nphpbsp;  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

      46: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;

      49: astore_1

      50: iinc          2, 1

      53: goto          25

      56: return

可以看出先创建String对象aaa,之后创建StringBuilder并初始化StringBuilder append aaa,然后创建bbb对象,并append(  bbb),然后我们发现在循环中依旧创建了一个新的StringBuilder,也就是没经过一次循环都要创建一个新的StringBuilder对象。

这时我们做一个优化,提前创建StringBuilder对象

String a = "aaa";
a += "bbb";
StringBuilder sb = new StringBuilder(a);
for(int i=0;i<5;i++){
    sb.append("ccc");
}

    Code:

       0: ldc           #2                  // String aaa

       2: astore_1

       3: new           #3                  // class java/lang/StringBuilder

       6: dup

       7: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V

      10: aload_1

      11: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

      14: ldc           #6                  // String bbb

      16: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

      19: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;

      22: astore_1

      23: new           #3                  // class java/lang/StringBuilder

      26: dup

      27: aload_1

      28: invokespecial #8                  // Method java/lang/StringBuilder."<init>"编程客栈:(Ljava/lang/String;)V

      31: astore_2

      32: iconst_0

      33: istore_3

      34: iload_3

      35: iconst_5

      36: if_icmpge     52

      39: aload_2

      40: ldc           #9                  // String ccc

      42: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

      45: pop

      46: iinc          3, 1

      49: goto          34

      52: return

可以看出循环体跳回34行,并不会不断地创建新的StringBuilder,大大提高了效率和减小了垃圾数量!,所以我们要注意自己的写法!避免无谓的消耗

总结

到此这篇关于Java中字符串String的+和+=及循环操作String原理的文章就介绍到这了,更多相关Java字符串String+和+=内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新开发

开发排行榜