美文网首页
String简介

String简介

作者: 一路花开_8fab | 来源:发表于2018-07-20 22:08 被阅读0次

    字符串操作是计算机程序设计中最常见的行为。java中的String 类被声明为final class(无法被继承),所有属性也都是final的(无法修改)。由于其不可变性,类似拼接、裁剪字符串等动作,都会产生新的String对象。String的不可变性也带来了天然的线程安全特性。
    不可变性也带来了拼接等操作效率低下的问题,StringBuilder(非线程安全)与StringBuffer(线程安全)就是为了解决这个问题而提供的类。

    1.重载“+”与StringBuilder

    public class Test {
    
        public static void main(String[] args) {
            String str1 = "abc" +  "def" + "ghi";
            System.out.println(str1);
    
            String str2 = "";
            for(int i = 0; i < 20; i ++) {
                str2 += "a";
            }
            System.out.println(str2);
    
            StringBuilder str3 = new StringBuilder();
            for(int i = 0; i < 20; i ++) {
                str3.append("a");
            }
            System.out.println(str3.toString());
    
    
        }
    
    }
    

    通过javap反编译以上代码

    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 abcdefghi
           2: astore_1
           3: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
           6: aload_1
           7: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
          10: ldc           #5                  // String
          12: astore_2
          13: iconst_0
          14: istore_3
          15: iload_3
          16: bipush        20
          18: if_icmpge     47
          21: new           #6                  // class java/lang/StringBuilder
          24: dup
          25: invokespecial #7                  // Method java/lang/StringBuilder."<init>":()V
          28: aload_2
          29: invokevirtual #8                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          32: ldc           #9                  // String a
          34: invokevirtual #8                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          37: invokevirtual #10                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
          40: astore_2
          41: iinc          3, 1
          44: goto          15
          47: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
          50: aload_2
          51: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
          54: new           #6                  // class java/lang/StringBuilder
          57: dup
          58: invokespecial #7                  // Method java/lang/StringBuilder."<init>":()V
          61: astore_3
          62: iconst_0
          63: istore        4
          65: iload         4
          67: bipush        20
          69: if_icmpge     85
          72: aload_3
          73: ldc           #9                  // String a
          75: invokevirtual #8                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          78: pop
          79: iinc          4, 1
          82: goto          65
          85: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
          88: aload_3
          89: invokevirtual #10                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
          92: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
          95: return
    }
    
    1. 从反编译结果可以看出:
    • 第0行,"abc" + "def" + "ghi"被编译器优化为abcdefghi(不同版本的编译器效果不同,有些是通过StringBuilder进行优化)
    1. 也许你会觉得反正编译器会自动地优化性能,可以随意使用String对象,但是看下编译器对str2生成过程的优化
    • 第18行:对堆栈中的操作数进行“大于或等于的整数比较运算”,循环结束时跳到第47行
    • 第44行:返回循环的起始点,第15行
      重点是:StringBuilder是在循环体内构造的,没经过一次循环,就会创建一个StringBuilder对象
    1. 来看编译器对str3生成过程的优化,StringBuilder是在循环体外构造的,而且循环体的代码更简短。

    当你为类编写toString()方法时,如果字符串操作比较简单,那就可以信赖编译器,它会为你合理地构造最终的字符串结果;但是,如果你要在toString()方法中使用循环,那么最好自己创建一个StringBuilder对象,用它来构造最终的结果。

    相关文章

      网友评论

          本文标题:String简介

          本文链接:https://www.haomeiwen.com/subject/cxfcmftx.html