Sting/StringBuffer/StringBuilder区别

    按我的习惯,使用StringBuffer比使用StringBuilder多得多,因为在我的记忆中,曾经看过一篇文章,忘记是谁写的了,那篇文章告诉我StringBuffer是非线程安全的,而StringBuilder是线程安全的,直到今天我又查询了一下两者的区别,发现StringBuffer才是线程安全的。这让我迷惑了,还是亲自去查询一下源码吧:

 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{

    /** 省略部分代码 */
    @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);
        }
    }
    @Override
    public synchronized void setCharAt(int index, char ch) {
        if ((index < 0) || (index >= count))
            throw new StringIndexOutOfBoundsException(index);
        toStringCache = null;
        value[index] = ch;
    }

    @Override
    public synchronized StringBuffer append(Object obj) {
        toStringCache = null;
        super.append(String.valueOf(obj));
        return this;
    }

    @Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }
    /** 省略部分代码 */
}


    从源码看出,StringBuffer很多方法都使用了synchronized进行同步,所以它是线程安全的,而StringBuilder是非线程安全的。所以在单线程中,StringBuilder的效率要高于StringBuffer。看来以后我得改改习惯,优先考虑使用StringBuilder了。

    再说说String类,String是一个特殊的引用类,它是一个不可变的字符串:

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

    /** Cache the hash code for the string */
    private int hash; // Default to 0

    /** 省略部分代码 */

    public native String intern();
 }


    之所以说它不可变,是因为其内部使用final char[]类型来存储字符串,final字段经过初始化后不能再次改变。

    值得一提的是,String提供了一个方法intern(),它的作用在于:返回字符串对象的规范化表示形式。当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。

        String a = "a";
        String aa = new String(a);
        System.out.println(a == aa);  //false
        System.out.println(a == aa.intern());  //true

    与String相较而言,StringBuffer和StringBuilder则是可变字符串。

标签: JAVA

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.jsunw.com/?post=16

相关推荐

你肿么看?

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。