String、StringBuffer 和 StringBuilder
不可变的 String
-
String
对象是不可变的。而每一个看起来会修改String
值的方法,实际上都是创建了一个新的String
对象。 - 每次将
String
对象作为参数时,实际上传递的是一个引用的拷贝。
String 重载 + 运算符
我们经常使用加号来拼接运算符,这次来了解一下 + 是如何去拼接字符串的。
public class Demo {
public static void main(String[] args) {
String str = new String("123");
str += "456";
System.out.println(str);
}
}
上方几行代码简单的实现了字符串的拼接功能,我们使用指令 javap -c Demo
后,得到以下的字节码:
public static void main(java.lang.String[]);
Code:
0: new #2 // class java/lang/String
3: dup
4: ldc #3 // String 123
6: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
9: astore_1
10: new #5 // class java/lang/StringBuilder
13: dup
14: invokespecial #6 // Method java/lang/StringBuilder."<init>":()V
17: aload_1
18: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: ldc #8 // String 456
23: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
26: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
29: astore_1
30: getstatic #10 // Field java/lang/System.out:Ljava/io/PrintStream;
33: aload_1
34: invokevirtual #11 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
37: return
可以看到字节码中,编译器 new 了一个 StringBuilder
对象,然后调用两次 append()
方法拼接字符串,最后调用 toString()
方法返回一个新的 String
对象,为 str
赋值。
-
什么时候使用 StringBuilder?
如果在for
中使用+/+=
拼接字符串,会在每次循环后创建一个新的StringBuilder
对象,所以在循环时,使用StringBuilder
代替String
的拼接更加高效。 -
什么时候使用 StringBuilder?
StringBuilder
是在 JAVA SE5 引入的,而在这之前的StringBuffer
是线程安全的,但因此开销比较大。
实际上就是所有方法加同步而已。
网友评论