Java中String、StringBuilder、StringBuffer是我们再熟悉不过的类型了,那么它们之间到底有啥区别呢。
首先,String类型是不可变的,StringBuilder、StringBuffer是可变的。
其次,StringBuilder与StringBuffer类似,无非就是在单线程的情况下StringBuilder要比StringBuffer快。如果要确保线程安全,那就用StringBuffer。
就这么两点。下面看一段代码感受一下String类型拼接,编译器到底是怎么处理的。
package strings;
public class Concatenation {
public static void main(String[] args) {
String mango = "mango";
String s = "abc" + mango + "def" + 47;
System.out.println(s);
}
} /* Output:
abcmangodef47
用javap反编译一下上面的class文件
javap -c Concatenation.class
于是得到以下字节码:
Compiled from "Concatenation.java"
public class strings.Concatenation {
public strings.Concatenation();
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 mango
2: astore_1
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<init>":
()V
10: ldc #5 // String abc
12: invokevirtual #6 // Method java/lang/StringBuilder.append:(L
java/lang/String;)Ljava/lang/StringBuilder;
15: aload_1
16: invokevirtual #6 // Method java/lang/StringBuilder.append:(L
java/lang/String;)Ljava/lang/StringBuilder;
19: ldc #7 // String def
21: invokevirtual #6 // Method java/lang/StringBuilder.append:(L
java/lang/String;)Ljava/lang/StringBuilder;
24: bipush 47
26: invokevirtual #8 // Method java/lang/StringBuilder.append:(I
)Ljava/lang/StringBuilder;
29: invokevirtual #9 // Method java/lang/StringBuilder.toString:
()Ljava/lang/String;
32: astore_2
33: getstatic #10 // Field java/lang/System.out:Ljava/io/Prin
tStream;
36: aload_2
37: invokevirtual #11 // Method java/io/PrintStream.println:(Ljav
a/lang/String;)V
40: return
}
在12到21行编译器将String转换为StringBuilder,这样做就是为了更高效。