Java之String+StringBuffer+StringBuilder

Java中常用的字符串类有:String、StringBuffer、StringBuilder

 

1、String 是不可变的字符串(字符串常量),也是线程安全的。

     String类的源码中组成字符串的数组是被 “ final ” 所修饰的, private final char value[]; 所以String中的对象是不可变的(可以理解为常量),因此它也是线程安全的。

     String是不可变的,因此对String字符串的操作,实际上就是在不断的创建新的String对象,而原来的对象就会变为垃圾被GC回收掉,这样执行效率会很低。

2、StringBuffer 和 StringBuilder 是可变的字符串,其中StringBuffer是线程安全的,StringBuilder是非线程安全的。      

  如StringBuffer 和 StringBuilder 的类结构图所示:
  二者都继承了公共的抽象父类AbstractStringBuilder,在 AbstractStringBuilder 的源码中也是使用字符数组保存字符串。char[] value; 因此二者都是可变的字符串。
  StringBuffer 和 StringBuilder 是可变的,因为对此二者字符串的操作实际上是在一个对象上操作的,因此效率高于String。

  StringBuffer   所有公开方法或被调用方法都加了同步锁(被synchronized修饰)所以StringBuffer 是线程安全的,
  StringBuilder 并没有对方法加同步锁(没有被synchronized修饰)所以StringBuilder是线程不安全的。

 

StringBuffer 和 StringBuilder 的缓冲区结构:

StringBuffer 代码片段:
private transient char[] toStringCache;
@Override
public synchronized String toString() {
  if (toStringCache == null) {
    toStringCache = Arrays.copyOfRange(value, 0, count);  
  }
  return new String(toStringCache, true);   // 使用缓存区的 toStringCache 值来构造一个字符串
}

StringBuilder 代码片段:
@Override
public String toString()
  return new String(value, 0, count);       // 直接复制一次字符数组来构造一个字符串
}

以上代码片段比较可以看出:缓存也是对 StringBuffer 的一个优化,不过StringBuffer 的toString 方法仍然是同步的。

3.StringBuffer 和 StringBuilder 和String的性能总结:

    String 为字符串常量,一旦创建是不可变的,也是线程安全的。
    StringBuffer 和 StringBuilder 为字符串变量,创建之后是可变的,
    StringBuffer  是线程安全的,它所有的公开方法都加了同步锁,所以在多线程中使用性能更好。
    StringBuilder是非线程安全的,它的方法都没有加同步锁(在多线程中有时会报错),StringBuilder在单线程中性能远高于StringBuffer。
    所以 StringBuffer 更适用于在多线程操作中,StringBuilder 则适用于在单线程中操作,String适用于少量的字符串操作。

 

 

 

 

猜你喜欢

转载自www.cnblogs.com/java-1230/p/10286902.html
今日推荐