以下内容皆是基于JDK1.8之后的版本进行的讨论和验证,并且使用javap -v指令显示底层的汇编指令从而查看真实过程:
String进行字符串拼接:
上代码
测试样例:
class Main{
public static void main(String[] args){
String a="asd";
a=a+"bd";
}
}
调用javap指令的结果
{
Main();
descriptor: ()V
flags:
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 1: 0
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=1
0: ldc #2 // String asd
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 bd
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
LineNumberTable:
line 3: 0
line 4: 3
line 5: 23
}
可知,当我们使用“+”拼接字符串的时候,实际上是创建了一个StringBuilder对象,并使用该对象的append方法进行字符串拼接,然后将得到的字符串通过toString方法返回给字符串对象。
经过测试可知,代码如下:
class Main{
public static void main(String[] args){
String b="ljk";
b=b+"qwe";
String a="asd";
a=a+"bd";
a=a+b;
b=a+b;
}
}
当我们需要使用“+”多次拼接字符串的时候,每次使用“+”,都会创建一个StringBuilder的对象,然后执行上述过程,得到拼接后的结果的字符串。
因此,String字符串的“+”拼接的效率相对于StringBuilder和StringBuffer来说还是比较低下的,在进行字符串拼接时还是应该尽量使用StringBuilder和StringBuffer方法,其中,StringBuffer因为部分函数通过synchronized关键字声明,所以线性安全,而StringBuilder则线性不安全,但在单线程中的进行字符串拼接时,StringBuilder的效率高于StringBuffer。