一、简介:
- String : 是java.lang包中的immutable类,String里面所有的属性几乎也是final。由于它的不可变性,类似拼接、裁剪字符串等动作都会产生大量无用的中间对象。由于字符串操作在项目中很常见,所以对String的操作对项目的性能往往有很明显的影响。
- StringBuffer(JDK1.0) : 这个类是为了解决大量拼接时产生多余对象的问题而提供的一个类,提供append和add方法,可以将字符串添加到已有序列的末尾或指定位置。它的本质是一个线程安全的可修改的字符序列,把所有修改数据的方法都加上了synchronized。StringBuffer保证了线程的安全,也带来了多余的开销。
- StringBuilder (JDK5.0): StringBuilder的功能与StringBuffer一样。但是区别是StringBuilder没有处理线程安全,减少了开销。
二、三者区别:
- String 是只读字符串,声明的是不可变的对象,每次操作都会生成新的String对象,然后将指针指向新的String对象。
- StringBuffer 和 StringBuilder 表示的字符串对象都可以直接进行修改,二者都继承了 AbstractStringBuilder。AbstractStringBuilder内部都提供了一个自动扩容机制,当发现长度不够的时候(初始默认长度是16),会自动进行扩容工作,扩展为原数组长度的2倍加2,创建一个新的数组,并将数组的数据复制到新数组,所以对于拼接字符串效率要比String要高。
- 线程安全性:StringBuffer由于很多方法都被 synchronized 修饰了所以线程安全,但是当多线程访问时,加锁和释放锁的过程很平凡,所以效率相比StringBuilder要低。StringBuilder相反执行效率高,但是线程不安全。所以单线程环境下推荐使用 StringBuilder,多线程环境下推荐使用 StringBuffer。
- 执行速度:StringBuilder > StringBuffer > String。
三、适用场景:
- 在字符串不经常发生变化的业务场景优先使用String(代码更清晰简洁)。如常量的声明,少量的字符串操作(拼接,删除等)。
- 在单线程情况下,如有大量的字符串操作情况,应该使用StringBuilder来操作字符串。不能使用String"+"来拼接而是使用,避免产生大量无用的中间对象,耗费空间且执行效率低下(新建对象、回收对象花费大量时间)。如JSON的封装等。
- 在多线程情况下,如有大量的字符串操作情况,应该使用StringBuffer。如HTTP参数解析和封装等。