在 Java 中,String
类是不可变(immutable)的,而 StringBuffer
和 StringBuilder
是可变(mutable)的。这有几个原因和影响:
String 是不可变的:
-
安全性:不可变性意味着一旦一个
String
对象被创建,它的内容就不能改变。这是线程安全的,因为多个线程可以同时访问同一个String
对象,而不用担心其中一个会修改它。 -
哈希码缓存:由于
String
是不可变的,其哈希码也是不变的。这使得String
特别适用于作为哈希表的键。 -
字符串池:Java 中有一个字符串池(String pool)机制,这个机制允许相同的字符串字面量共享同一个
String
对象,以节省内存。这只有在String
是不可变的情况下才是安全的。 -
不可变对象是简单的:不可变对象更容易使用、测试和理解。
例如:
String s = "Hello";
s = s + " World"; // 实际上创建了一个新的字符串对象
在这里,s + " World"
实际上创建了一个全新的 String
对象,原来的 String
对象 "Hello"
仍然存在但没有被改变。
StringBuffer 是可变的:
-
性能优化:与
String
相比,StringBuffer
(和StringBuilder
)是可变的,意味着你可以在不创建新对象的情况下修改其内容。这通常在你需要频繁修改字符串时更加高效。 -
API 设计:
StringBuffer
提供了多种修改字符串的方法,如append
,insert
,delete
,reverse
等,这些都是原地(in-place)操作。 -
线程安全:与
StringBuilder
不同,StringBuffer
是线程安全的,因为它的大多数方法都是同步的(synchronized)。
例如:
StringBuffer buffer = new StringBuffer("Hello");
buffer.append(" World"); // 直接修改原有对象
在这里,buffer.append(" World")
直接修改了 buffer
对象的内容,没有创建新的对象。
因为 String
是不可变的,所以它通常更适用于不需要修改的字符串或作为哈希表的键。而 StringBuffer
和 StringBuilder
由于其可变性,更适用于需要频繁修改的字符串操作。