String是典型的Immutable(不可变)类,被声明为final class,所有属性都是final的。由于它的不可变性,类似拼接、截取字符串等操作都会产生新的String对象,往往编码中常常对字符串进行操作,所以操作的效率往往对应用性能有明显影响。
StringBuffer 是为了解决上面提到的因拼接产生太多中间对象问题而提供的一个类,我们可以用append 或者add方法,把字符串添加到已有序列末尾或者指定位置。StringBuffer本质是一个线程安全的可修改字符序列,它保证了线程安全(通过把各种修改数据的方法都加上synchronized关键字实现),也随之带来了额外的性能开销,若无线程安全的需要,可以使用StringBulider。
深入分析:
1.字符串的设计和实现考量
StringBuffer 和StringBulider底层都是利用可修改的数组(java9是byte)数组,二者都继承了AbstractStringBulider,里面包含了基本操作,区别仅仅在于方法是否加了synchronized。
这个数组构建时是初始字符串长度加16,如果没有构建时输入最初的字符串,那么初始值就是16。如果我们能预估需要的大小,最好制定其大小,避免多次扩容带来的开销,扩容需要创建新的数组,还要进行arrayCopy。
//不带字符串初始化,默认分配16byte StringBuilder stringBuilder = new StringBuilder(); //带字符串初始化,初始化字符串长度+16byte StringBuilder sb = new StringBuilder().append("nihao").append("ggsimida"); //指定大小50byte StringBuilder ssb = new StringBuilder(50).append("nihao").append("ggsimida");
2.字符串缓存
各版本jdk的实现
3.String自身演化
java9将字符串存储方式从char数组,改变为一个byte数组加上一个标识编码的coder,极端情况下最长字符串大小变小了,但是紧凑型字符串优势巨大,更小的内存,更快的操作速度。