首先,String是不可变长的,当然也是线程安全的了(因为不可变长)。

String在String str = "艾弗森";

       str = str + "乔丹";

这种情况的时候,堆内存里面会有一个“艾弗森”字符串和“艾弗森乔丹”字符串,str是指向“艾弗森乔丹”,而“艾弗森”是没有被任何变量引用的。也就造成了内存泄露。

其次,StringBuilder和StringBuffer都是可变长的,但StringBuffer是线程安全的,也就是多线程操作的时候它不会发生混乱,可以正常工作,因为它有锁那样的机制,增加了synchronized修饰符。StringBuder则是单线程安全的,只能单线程使用,多线程操作会不安全,但不用到多线程的时候StringBuder效率是三者最高的,因为StringBuffer的锁机制会消耗一定的效率。

   StringBuffer str = "艾弗森";

   str.append("乔丹");

   StringBuder str1 = "樱木花道";

   str1.append("流川枫");

这两个不会造成内存泄露。

append()函数对于各种参数类型和各种情况下的具体操作,在Java里面的定义如下:

public AbstractStringBuilder append(Object obj) {    //AbstractStringBuilder是StringBuffer和StringBuilder的父类
        return append(String.valueOf(obj));
    }
  public AbstractStringBuilder append(String str) {
        if (str == null) str = "null";
        int len = str.length();//=16
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);//count的默认值都是16
        count += len;//String.size()+16
        return this;
    }
    // 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;
    }
    // Documentation in subclasses because of synchro difference
    public AbstractStringBuilder append(CharSequence s) {
        if (s == null)
            s = "null";
        if (s instanceof String)
            return this.append((String)s);
        if (s instanceof StringBuffer)
            return this.append((StringBuffer)s);
        return this.append(s, 0, s.length());
    }
 public AbstractStringBuilder append(CharSequence s, int start, int end) {
        if (s == null)
            s = "null";
        if ((start < 0) || (start > end) || (end > s.length()))
            throw new IndexOutOfBoundsException(
                "start " + start + ", end " + end + ", s.length() "
                + s.length());
        int len = end - start;
        ensureCapacityInternal(count + len);
        for (int i = start, j = count; i < end; i++, j++)
            value[j] = s.charAt(i);
        count += len;
        return this;
    }
public AbstractStringBuilder append(char[] str) {
        int len = str.length;
        ensureCapacityInternal(count + len);
        System.arraycopy(str, 0, value, count, len);
        count += len;
        return this;
    }
  public AbstractStringBuilder append(char str[], int offset, int len) {
        if (len > 0)                // let arraycopy report AIOOBE for len < 0
            ensureCapacityInternal(count + len);
        System.arraycopy(str, offset, value, count, len);
        count += len;
        return this;
    }
  public AbstractStringBuilder append(boolean b) {
        if (b) {
            ensureCapacityInternal(count + 4);
            value[count++] = 't';
            value[count++] = 'r';
            value[count++] = 'u';
            value[count++] = 'e';
        } else {
            ensureCapacityInternal(count + 5);
            value[count++] = 'f';
            value[count++] = 'a';
            value[count++] = 'l';
            value[count++] = 's';
            value[count++] = 'e';
        }
        return this;
    }
 public AbstractStringBuilder append(char c) {
        ensureCapacityInternal(count + 1);
        value[count++] = c;
        return this;
    }
 public AbstractStringBuilder append(int i) {
        if (i == Integer.MIN_VALUE) {
            append("-2147483648");
            return this;
        }
        int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
                                     : Integer.stringSize(i);
        int spaceNeeded = count + appendedLength;
        ensureCapacityInternal(spaceNeeded);
        Integer.getChars(i, spaceNeeded, value);
        count = spaceNeeded;
        return this;
    }
 public AbstractStringBuilder append(long l) {
        if (l == Long.MIN_VALUE) {
            append("-9223372036854775808");
            return this;
        }
        int appendedLength = (l < 0) ? Long.stringSize(-l) + 1
                                     : Long.stringSize(l);
        int spaceNeeded = count + appendedLength;
        ensureCapacityInternal(spaceNeeded);
        Long.getChars(l, spaceNeeded, value);
        count = spaceNeeded;
        return this;
    }
 public AbstractStringBuilder append(float f) {
        new FloatingDecimal(f).appendTo(this);
        return this;
    }
 public AbstractStringBuilder append(double d) {
        new FloatingDecimal(d).appendTo(this);
        return this;
    }