• Java中String、StringBuilder、StringBuffer常用源码分析及比较(三):String、StringBuilder、StringBuffer比较


    看这篇随笔之前请务必先看前面两章:

    Java中String、StringBuilder、StringBuffer常用源码分析及比较(一):String源码分析

    Java中String、StringBuilder、StringBuffer常用源码分析及比较(二):StringBuilder、StringBuffer源码分析

    这里讲解了这三个类型的源码,也或多或少的讲解了他们的不同。

    下面进入正题:

    相同点:

    一、成员变量:

      1.通过之前对源码的分析,可以知道他们都是通过char数组value来存字符串的

      2.StringBuilder与StringBuffer都继承自AbstractStringBuilder,且他们的构造方法基本都来自AbstractStringBuilder

      3.String、StringBuilder、StringBuffer都实现了CharSequence接口,,这个接口定义如下方法

    /**
         * 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();

    二、成员方法:

      1.StringBuilder与StringBuffer中大多方法都来自于他们共同的父类AbstractStringBuilder,所实现的功能基本一模一样。

    不同点:

    一、成员变量

      1.虽然String、StringBuilder、StringBuffer都是以char数组value来存字符串,但是String中value是final的(即构造方法初始化后无法被修改),而其余两个却没有,所以再做拼接时,String需要不停的新建String对象,并用copy方法来实现拼接,而StringBuilder、StringBuffer则可在value容量足够情况下在value后拼接字符串;

    二、成员方法

      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的线程安全性有关,但是想不到具体细节,留下一个疑虑点,希望知道的小伙伴能给一下答案,谢谢!

  • 相关阅读:
    制定并分享愿景 领导的艺术之一
    不要非黑即白,有些数据即使只有90%的准确,也是有用的
    双赢的思维考虑问题
    利用一切机会丰富自己的知识,利用一切机会调整自己的行为,为了达成目标而与他人合作,取得共赢 update by June 2012
    数据说话 说服别人
    对重要的事情,要很快做出反应
    You can if you think you can
    宽容的心态,开明的头脑
    DataGridView上下移动行及设置当前行
    sql 数据库、表
  • 原文地址:https://www.cnblogs.com/tz346125264/p/7625568.html
Copyright © 2020-2023  润新知