String不可变,StringBuffer和StringBuilder是可变的。
1、String是只读字符串,也就意味着String引用的字符串内容是不可以被改变的,但是我们往往会有这样一个误解:
String str = "abc";
str = "bcd";
对于上面的代码来说,字符串明明是可以改变的呀,为啥是不可变的呢?其实不是,str只是一个引用对象,它指向一个字符串对象是"abc",第二行代码只是让它指向了一个新的字符串"bcd",而"abc"对象并没有任何改变。
而String的源码是这样的:
private final char value[];
StringBuffer是这样的:
private transient char[] toStringCache;
StringBuilder也是类似
为什么String不可变就是因为它底层是用final关键字修饰
2、StringBuffer和StringBuilder表示的字符串可以直接进行修改。
3、StringBuilder是java5引入的,它和StringBuffer的方法完全相同,区别在于StringBuilder是在单线程下使用的多线程下不安全,因为底层没有用synchronized修饰,它的效率也要比StringBuilder要高。
value是底层对应的数组
count有多少被占用
扩容长度:原先的长度*2+2
当原先value对应的数组放满时,会重新指向一个新的数组并进行扩容
数组的扩容:
value = Arrays.copyof(value,newCapacity(minimumCapacity));
总结:
类型 | 特点 | 适用场景 |
String | 不可变,线程安全 | 操作少量数据或不需要操作数据 |
StringBuilder | 可变,线程不安全 | 需要频繁操作数据且不用考虑线程安全性 |
StringBuffer | 可变,线程安全,性能较低 | 需要频繁操作数据且需要考虑线程安全 |
在单线程下用尽量不使用StringBuffer,使用StringBuilder效率更高!!!