# StringBuilder 底层属性:value,count。 可变于不可变字符串 String是一个不可变字符串,这里的不可变是指常量池中的对象不变;在引用地址不变的情况下,不能变; StringBuilder是一个可变字符串,在堆中,它的引用对象地址始终不变,在引用地址不变的情况下,字符串可以变。直接append方法。 编译器对`String`做了特殊处理,使得我们可以直接用`+`拼接字符串。虽然可以直接拼接字符串,但是,在循环中,每次循环都会创建新的字符串对象,然后扔掉旧的字符串。这样,绝大部分字符串都是临时对象,不但浪费内存,还会影响GC效率。 ```java String s = ""; for (int i = 0; i < 1000; i++) { s = s + "," + i; } ``` 为了能高效拼接字符串,Java标准库提供了`StringBuilder`,它是一个可变对象,可以预分配缓冲区,这样,往`StringBuilder`中新增字符时,不会创建新的临时对象 ```java StringBuilder sb = new StringBuilder(1024); for (int i = 0; i < 1000; i++) { sb.append(','); sb.append(i); } String s = sb.toString(); ``` `StringBuilder`还可以进行链式操作 ```java public class Main { public static void main(String[] args) { var sb = new StringBuilder(1024); sb.append("Mr ") .append("Bob") .append("!") .insert(0, "Hello, "); System.out.println(sb.toString()); } } ``` 注意:对于普通的字符串`+`操作,并不需要我们将其改写为`StringBuilder`,因为Java编译器在编译时就自动把多个连续的`+`操作编码为`StringConcatFactory`的操作。在运行期,`StringConcatFactory`会自动把字符串连接操作优化为数组复制或者`StringBuilder`操作。 你可能还听说过`StringBuffer`,这是Java早期的一个`StringBuilder`的线程安全版本,它通过同步来保证多个线程操作`StringBuffer`也是安全的,但是同步会带来执行速度的下降。 `StringBuilder`和`StringBuffer`接口完全相同,现在完全没有必要使用`StringBuffer`。 ### String,StringBuilder,StringBuffer String 不可变 StringBuilder和StringBuffer可变。 StringBuilder效率高,线程不安全。 StringBuffer效率低,线程安全。