String类 "+"的使用运行原理

来源:互联网 发布:linux top cpu 编辑:程序博客网 时间:2024/05/04 11:33
public class Test{
 public String s5 = "d";
 public Integer s8 =1;
 public String s7 = new String("g");
 public void x()
 {
  String s5 = "e";
 }
  public static void y()
 {
  String s6 = "f";
 }
  public static void main(String[] args){
        String s1 = "a";
        String s2 = "b";
        String s3 = "c";
 
 
        String h7 = s1 + s2 + s3;
        String h8 = "a"+"b"+"c";
     
        String h1 = s1+"b"+"c";
       
   
  String h9 =s1;
  h9 = h9+"b"+"c";
 
  String h10 =s1;
  h10 += "b"+"c";
 
  String h3 = s1+s2;
  String h4 = h3+s3;
 
  String h5 = "a"+"b";
  String h6 = h3+s3;
 
  StringBuilder result = new StringBuilder();
  String s4 = result.append(s1).append(s2).append(s3).toString();
 
    }
}



字节码结果如下:
  public static void main(java.lang.String[]);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=15, args_size=1
         0: ldc #12 // String a
         2: astore_1
         3: ldc #13 // String b
         5: astore_2
         6: ldc #14 // String c
         8: astore_3
         9: new #15 // class java/lang/StringBuilder
        12: dup
        13: invokespecial #16 // Method java/lang/StringBuilder. "<init>":()V 
        16: aload_1
        17: invokevirtual #17 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
        20: aload_2
        21: invokevirtual #17 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
        24: aload_3
        25: invokevirtual #17 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
        28: invokevirtual #18 // Method java/lang/StringBuilder. toString:()Ljava/lang/String; 
        31: astore 4
        33: ldc #19 // String abc
        35: astore 5
        37: new #15 // class java/lang/StringBuilder
        40: dup
        41: invokespecial #16 // Method java/lang/StringBuilder. "<init>":()V 
        44: aload_1
        45: invokevirtual #17 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
        48: ldc #13 // String b
        50: invokevirtual #17 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
        53: ldc #14 // String c
        55: invokevirtual #17 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
        58: invokevirtual #18 // Method java/lang/StringBuilder. toString:()Ljava/lang/String; 
        61: astore 6
        63: aload_1
        64: astore 7
        66: new #15 // class java/lang/StringBuilder
        69: dup
        70: invokespecial #16 // Method java/lang/StringBuilder. "<init>":()V 
        73: aload 7
        75: invokevirtual #17 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
        78: ldc #13 // String b
        80: invokevirtual #17 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
        83: ldc #14 // String c
        85: invokevirtual #17 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
        88: invokevirtual #18 // Method java/lang/StringBuilder. toString:()Ljava/lang/String; 
        91: astore 7
        93: aload_1
        94: astore 8
        96: new #15 // class java/lang/StringBuilder
        99: dup
       100: invokespecial #16 // Method java/lang/StringBuilder. "<init>":()V 
       103: aload 8
       105: invokevirtual #17 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
       108: ldc #20 // String bc
       110: invokevirtual #17 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
       113: invokevirtual #18 // Method java/lang/StringBuilder. toString:()Ljava/lang/String; 
       116: astore 8
       118: new #15 // class java/lang/StringBuilder
       121: dup
       122: invokespecial #16 // Method java/lang/StringBuilder. "<init>":()V 
       125: aload_1
       126: invokevirtual #17 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
       129: aload_2
       130: invokevirtual #17 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
       133: invokevirtual #18 // Method java/lang/StringBuilder. toString:()Ljava/lang/String; 
       136: astore 9
       138: new #15 // class java/lang/StringBuilder
       141: dup
       142: invokespecial #16 // Method java/lang/StringBuilder. "<init>":()V 
       145: aload 9 
       147: invokevirtual #17 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
       150: aload_3
       151: invokevirtual #17 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
       154: invokevirtual #18 // Method java/lang/StringBuilder. toString:()Ljava/lang/String; 
       157: astore 10
       159: ldc #21 // String ab
       161: astore 11
       163: new #15 // class java/lang/StringBuilder
       166: dup
       167: invokespecial #16 // Method java/lang/StringBuilder. "<init>":()V 
       170: aload 9
       172: invokevirtual #17 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
       175: aload_3
       176: invokevirtual #17 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
       179: invokevirtual #18 // Method java/lang/StringBuilder. toString:()Ljava/lang/String; 
       182: astore 12
       184: new #15 // class java/lang/StringBuilder
       187: dup
       188: invokespecial #16 // Method java/lang/StringBuilder. "<init>":()V 
       191: astore 13
       193: aload 13
       195: aload_1
       196: invokevirtual #17 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
       199: aload_2
       200: invokevirtual #17 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
       203: aload_3
       204: invokevirtual #17 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
       207: invokevirtual #18 // Method java/lang/StringBuilder. toString:()Ljava/lang/String; 
       210: astore 14
       212: return
      LineNumberTable:
        line 14: 0
        line 15: 3
        line 16: 6
        line 19: 9
        line 21: 33
        line 23: 37
        line 26: 63
        line 27: 66
        line 29: 93
        line 30: 96
        line 32: 118
        line 33: 138
        line 35: 159
        line 36: 163
        line 39: 184
        line 40: 193
        line 42: 212
}
结论:对于+号的使用主要分为三类:常量和常量,常量和变量,变量和变量。

常量和常量:不需要调用StingBuilder类的append方法。编译器优化直接创建常量。
常量和变量:需要调用StringBuilder。一行+语句需要调用一次StringBuilder类,而其中的append方法调用次数取决一行+里面的变量和常量的数量。但是有一种特殊的形式例如  String h10 =s1;  h10 += "b"+"c"; 由于隐含h10参与运算,所以先append h10,接着编译器优化直接创建bc然后再append bc 所以调用了两次append。
变量和变量:需要调用StringBuilder类。一行+语句需要调用一次StringBuilder类,而其中的append方法调用次数取决一行+里面的变量数量

0 0
原创粉丝点击