Java中String、StringBuilder、StringBuffer經常使用源碼分析及比較(三):String、StringBuilder、StringBuffer比較 Java中String、S

看這篇隨筆以前請務必先看前面兩章:html

Java中String、StringBuilder、StringBuffer經常使用源碼分析及比較(一):String源碼分析java

Java中String、StringBuilder、StringBuffer經常使用源碼分析及比較(二):StringBuilder、StringBuffer源碼分析數組

這裏講解了這三個類型的源碼,也或多或少的講解了他們的不一樣。安全

下面進入正題:多線程

相同點:app

1、成員變量:less

  1.經過以前對源碼的分析,能夠知道他們都是經過char數組value來存字符串的源碼分析

  2.StringBuilder與StringBuffer都繼承自AbstractStringBuilder,且他們的構造方法基本都來自AbstractStringBuilderpost

  3.String、StringBuilder、StringBuffer都實現了CharSequence接口,,這個接口定義以下方法ui

/**
     * Returns the length of this character sequence.  The length is the number
     * of 16-bit <code>char</code>s in the sequence.</p>
     *
     * @return  the number of <code>char</code>s in this sequence
     */
    int length();

    /**
     * Returns the <code>char</code> value at the specified index.  An index ranges from zero
     * to <tt>length() - 1</tt>.  The first <code>char</code> value of the sequence is at
     * index zero, the next at index one, and so on, as for array
     * indexing. </p>
     *
     * <p>If the <code>char</code> value specified by the index is a
     * <a href="{@docRoot}/java/lang/Character.html#unicode">surrogate</a>, the surrogate
     * value is returned.
     *
     * @param   index   the index of the <code>char</code> value to be returned
     *
     * @return  the specified <code>char</code> value
     *
     * @throws  IndexOutOfBoundsException
     *          if the <tt>index</tt> argument is negative or not less than
     *          <tt>length()</tt>
     */
    char charAt(int index);

    /**
     * Returns a new <code>CharSequence</code> that is a subsequence of this sequence.
     * The subsequence starts with the <code>char</code> value at the specified index and
     * ends with the <code>char</code> value at index <tt>end - 1</tt>.  The length
     * (in <code>char</code>s) of the
     * returned sequence is <tt>end - start</tt>, so if <tt>start == end</tt>
     * then an empty sequence is returned. </p>
     *
     * @param   start   the start index, inclusive
     * @param   end     the end index, exclusive
     *
     * @return  the specified subsequence
     *
     * @throws  IndexOutOfBoundsException
     *          if <tt>start</tt> or <tt>end</tt> are negative,
     *          if <tt>end</tt> is greater than <tt>length()</tt>,
     *          or if <tt>start</tt> is greater than <tt>end</tt>
     */
    CharSequence subSequence(int start, int end);

    /**
     * Returns a string containing the characters in this sequence in the same
     * order as this sequence.  The length of the string will be the length of
     * this sequence. </p>
     *
     * @return  a string consisting of exactly this sequence of characters
     */
    public String toString();

2、成員方法:

  1.StringBuilder與StringBuffer中大多方法都來自於他們共同的父類AbstractStringBuilder,所實現的功能基本如出一轍。

 

不一樣點:

1、成員變量

  1.雖然String、StringBuilder、StringBuffer都是以char數組value來存字符串,可是String中value是final的(即構造方法初始化後沒法被修改),而其他兩個卻沒有,因此再作拼接時,String須要不停的新建String對象,並用copy方法來實現拼接,而StringBuilder、StringBuffer則可在value容量足夠狀況下在value後拼接字符串;

2、成員方法

  1.在String拼接中,有兩個方法,‘+’與concat方法、實現的效果同樣,不一樣的是concat沒有進行參數的判空,若參數爲null,就會報空指針異常,其他兩個都只有append方法拼接且該拼接不會新建對象(StringBuilder,StringBuffer);

  2.StringBuilder、StringBuffer一個線程安全、一個線程不安全,其實緣由也就來自於StringBuffer中append方法使用了synchronized來實現不容許多線程同時訪問;

 

疑惑點:

在StringBuilder、StringBuffer中其實還有一個不一樣點,先分別給出AbstractStringBuilder、StringBuffer、StringBuilder有關這部分的源碼

AbstractStringBuilder:

// Documentation in subclasses because of synchro difference
    public AbstractStringBuilder append(StringBuffer sb) {
        if (sb == null)
            return append("null");
        int len = sb.length();
        ensureCapacityInternal(count + len);
        sb.getChars(0, len, value, count);
        count += len;
        return this;
    }

StringBuffer:

/**
     * Appends the specified <tt>StringBuffer</tt> to this sequence.
     * <p>
     * The characters of the <tt>StringBuffer</tt> argument are appended,
     * in order, to the contents of this <tt>StringBuffer</tt>, increasing the
     * length of this <tt>StringBuffer</tt> by the length of the argument.
     * If <tt>sb</tt> is <tt>null</tt>, then the four characters
     * <tt>"null"</tt> are appended to this <tt>StringBuffer</tt>.
     * <p>
     * Let <i>n</i> be the length of the old character sequence, the one
     * contained in the <tt>StringBuffer</tt> just prior to execution of the
     * <tt>append</tt> method. Then the character at index <i>k</i> in
     * the new character sequence is equal to the character at index <i>k</i>
     * in the old character sequence, if <i>k</i> is less than <i>n</i>;
     * otherwise, it is equal to the character at index <i>k-n</i> in the
     * argument <code>sb</code>.
     * <p>
     * This method synchronizes on <code>this</code> (the destination)
     * object but does not synchronize on the source (<code>sb</code>).
     *
     * @param   sb   the <tt>StringBuffer</tt> to append.
     * @return  a reference to this object.
     * @since 1.4
     */
    public synchronized StringBuffer append(StringBuffer sb) {
        super.append(sb);
        return this;
    }

StringBuilder:

// Appends the specified string builder to this sequence.
    private StringBuilder append(StringBuilder sb) {
        if (sb == null)
            return append("null");
        int len = sb.length();
        int newcount = count + len;
        if (newcount > value.length)
            expandCapacity(newcount);
        sb.getChars(0, len, value, count);
        count = newcount;
        return this;
    }

    /**
     * Appends the specified <tt>StringBuffer</tt> to this sequence.
     * <p>
     * The characters of the <tt>StringBuffer</tt> argument are appended,
     * in order, to this sequence, increasing the
     * length of this sequence by the length of the argument.
     * If <tt>sb</tt> is <tt>null</tt>, then the four characters
     * <tt>"null"</tt> are appended to this sequence.
     * <p>
     * Let <i>n</i> be the length of this character sequence just prior to
     * execution of the <tt>append</tt> method. Then the character at index
     * <i>k</i> in the new character sequence is equal to the character at
     * index <i>k</i> in the old character sequence, if <i>k</i> is less than
     * <i>n</i>; otherwise, it is equal to the character at index <i>k-n</i>
     * in the argument <code>sb</code>.
     *
     * @param   sb   the <tt>StringBuffer</tt> to append.
     * @return  a reference to this object.
     */
    public StringBuilder append(StringBuffer sb) {
        super.append(sb);
        return this;
    }

能夠看到在父類、StringBuffer都有append(StringBuffer sb)這個方法,可是卻沒有append(StringBuilder sb),只有StringBuilder有,並且還定義爲private,我以爲可能這也跟StringBuilder、StringBuffer的線程安全性有關,可是想不到具體細節,留下一個疑慮點,但願知道的小夥伴能給一下答案,謝謝!

相關文章
相關標籤/搜索