欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

“+=”和append的区别

程序员文章站 2024-02-28 18:37:10
...

首先感谢大佬https://segmentfault.com/a/1190000018238445?utm_source=tag-newest
java
发布于 2019-02-21
“+=”和append的区别是面试中出现频率较高的一个题目了,下面我们就来分析一下这两者的区别吧。
首先看一下这段代码的结果:

String s1 = “a”;
String s2 = s1 + “b”;
System.out.println(s2 == “ab”); // false
输出结果是false;

javap将其反编译之后的结果如下:

public static void main(java.lang.String[]);
Code:
0: ldc #2 // String a
2: astore_1
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder.""????)V
10: aload_1
11: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
14: ldc #6 // String b
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_2
23: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;
26: aload_2
27: ldc #9 // String ab
29: if_acmpne 36
32: iconst_1
33: goto 37
36: iconst_0
37: invokevirtual #10 // Method java/io/PrintStream.println:(Z)V
40: return
根据结果我们可以看到:

虚拟机开始是定义了一个字符串”a“将其入栈;
然后new了一个StringBuilder对象,将”a“封装到Sb对象中;
之后用StringBuilder的append()方法来完成"a"和"b"的拼接;
所以这里的"ab"字符串本质上是一个StringBuilder对象,所以再去跟常量"ab"去比较的话会是false;
这样看来用"+"和append效率似乎是一样的,并没有像网上说的那样”+“操作比append()更消耗性能。

那下面我们来看一下这两者在循环中是什么结果:
首先是”+=“操作:

public static void main(String[] args) {
String[] arr = new String[]{“a”,“b”,“c”};
String result = “”;
for (int i = 0 ; i < arr.length; i ++) {
result += arr[i];
}
System.out.println(result);
}
反编译结果如下:

public static void main(java.lang.String[]);
Code:
0: iconst_3
1: anewarray #2 // class java/lang/String
4: dup
5: iconst_0
6: ldc #3 // String a
8: aastore
9: dup
10: iconst_1
11: ldc #4 // String b
13: aastore
14: dup
15: iconst_2
16: ldc #5 // String c
18: aastore
19: astore_1
20: ldc #6 // String
22: astore_2
23: iconst_0
24: istore_3
25: iload_3
26: aload_1
27: arraylength
28: if_icmpge 58
43,1 34%
31: new #7 // class java/lang/StringBuilder
34: dup
35: invokespecial #8 // Method java/lang/StringBuilder.""????)V
38: aload_2
39: invokevirtual #9 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
42: aload_1
43: iload_3
44: aaload
45: invokevirtual #9 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
48: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
51: astore_2
52: iinc 3, 1
55: goto 25
58: getstatic #11 // Field java/lang/System.out:Ljava/io/PrintStream;
61: aload_2
62: invokevirtual #12 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
65: return
可以看到从25: iload_3和55: goto 25两句构成了一个循环,而31: new #7 // class java/lang/StringBuilder创建StringBuilder对象语句在循环内,所以会创建多个
SB对象;

下面我们把代码改为append()实现:

public static void main(String[] args) {
    String[] arr = new String[]{"a","b","c"};
    StringBuilder result = new StringBuilder();
    for (int i = 0 ; i < arr.length; i ++) {
        result.append(arr[i]);
    }
    System.out.println(result);
}

反编译后:

public static void main(java.lang.String[]);
Code:
0: iconst_3
1: anewarray #2 // class java/lang/String
4: dup
5: iconst_0
85,7 68%
6: ldc #3 // String a
8: aastore
9: dup
10: iconst_1
11: ldc #4 // String b
13: aastore
14: dup
15: iconst_2
16: ldc #5 // String c
18: aastore
19: astore_1
20: new #6 // class java/lang/StringBuilder
23: dup
24: invokespecial #7 // Method java/lang/StringBuilder.""????)V
27: astore_2
28: iconst_0
29: istore_3
30: iload_3
31: aload_1
32: arraylength
33: if_icmpge 50
36: aload_2
37: aload_1
38: iload_3
39: aaload
40: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
43: pop
44: iinc 3, 1
47: goto 30
50: getstatic #9 // Field java/lang/System.out:Ljava/io/PrintStream;
53: aload_2
54: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
57: return
可以发现在由30: iload_3和47: goto 30构成的循环体内没有new操作,而是放到了循环外部
20: new #6 // class java/lang/StringBuilder

由此得出,在循环时使用+=会创建多个StringBuilder对象,而使用append(),只会创建一个。
所以我们在平时写代码的时候一定注意,不要再循环中使用+=操作,效率很低的。

相关标签: java