String及StringBuffer、StringBuilder解析

来源:互联网 发布:大脚插件mac更新 编辑:程序博客网 时间:2024/06/01 09:58

首先推荐一篇来自大神的博客http://blog.csdn.net/chengyingzhilian/article/details/7781858


  1. String类型

         String类型是长度不可变的字符串类型。参看String的定义源码:

              

public final class String    implements java.io.Serializable, Comparable<String>, CharSequence {    /** The value is used for character storage. */    private final char value[];    ......}可以看出String底层存储的方式是字符数组。声明为final类型,长度不可变。那么会有一个问题
String str1 = "abc";str1 = str1+"123";System.out.println(str1);
输出结果为:abc123.

这个字符串的长度不是变了吗?这是一个可变的吗?? 其实这俩行代码的执行过程是这样的:

首先创建对象str1,赋予一个"abc",然后再创建一个新的对象str1 ,用来执行第二行代码,也就是说我们之前对象str1并没有变化,所以我们说String类型是不可改变的对象了,由于这种机制,每当用String操作字符串时,实际上是在不断的创建新的对象,而原来的对象就会变为垃圾被GC回收掉,可想而知这样执行效率会有多底。

String类型支持共享,可以说String是线程安全的。

    2.StringBuffer类型和StringBuilder类型

StringBuffer与StringBuilder都是字符串变量,他们的长度是可变的。每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,这样就不会像String一样创建一些而外的对象进行操作了,当然速度就快了。

public class StringBufferTest {public static void main(String [] args) {StringBuffer str1 = new StringBuffer("hello");System.out.println(str1.hashCode());//366712642str1 = str1.append(" world");System.out.println(str1.hashCode());//366712642String str2 = "hello";System.out.println(str2.hashCode());//99162322str2 = str2 + "world";System.out.println(str2.hashCode());//-1524582912}}

可以简单的看一下StringBuffer的源码:

public final class StringBuffer    extends AbstractStringBuilder    implements java.io.Serializable, CharSequence{      //存储空间    private transient char[] toStringCache;    static final long serialVersionUID = 3388685877147921107L;      //构造方法,默认为16个字符的容量    public StringBuffer() {        super(16);    }   public StringBuffer(int capacity) {        super(capacity);    }    public StringBuffer(String str) {        super(str.length() + 16);        append(str);    }    public StringBuffer(CharSequence seq) {        this(seq.length() + 16);        append(seq);    }    @Override    public synchronized int length() {        return count;    }    @Override    public synchronized int capacity() {        return value.length;    }    @Override    public synchronized void ensureCapacity(int minimumCapacity) {        if (minimumCapacity > value.length) {            expandCapacity(minimumCapacity);        }    }     .......其他的成员方法}
可以看到他的成员方法全部添加同步了,所以StringBuffer是线程安全的。


StringBuilder是线程不安全的,但是它的执行效率却是最高的。通常情况下我们选择StringBuilder更能提高执行效率。

对于三者使用的总结: 1.如果要操作少量的数据用 = String

           2.单线程操作字符串缓冲区 下操作大量数据 = StringBuilder

           3.多线程操作字符串缓冲区 下操作大量数据 = StringBuffer


0 0