首先,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;
}
转载于:https://blog.51cto.com/icbcchina/1338616