1. String为不可变字符序列,用数组存储,可以理解为常量,线程安全。由于实际问题中存在字符串变动的情况,因此我们引入了StringBuffer类和StringBuilder(JDK1.5开始有)类
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[]; ................ }
2. 对于可变长字符序列StringBuffer和StringBuilder,AbstractStringBuilder 是它们的公共父类。StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的
abstract class AbstractStringBuilder implements Appendable, CharSequence { /** * The value is used for character storage. */ char[] value; ............. }
3. 在性能方面,每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象。StringBuffer 每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用 StringBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。
4. 使用场景
- 在字符串不经常变化的场景中可以使用 String 类,例如常量的声明、少量的变量运算等
- 在频繁进行字符串运算(如拼接、替换、和删除等),并且运行在单线程的环境中,则可以考虑使用 StringBuilder,如 SQL 语句的拼装、JSON 封装等
- 在频繁进行字符串运算(如拼接、替换、删除等),并且运行在多线程环境中,则可以考虑使用 StringBuffer,例如 XML 解析、HTTP 参数解析和封装等