源码级StringBuffer和StringBuilder以及String区别
作为一个面试常问的问题:
首先看一下源码:
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
这是源码从这里可以看出两者都可序列化,CharSequence是一个字符序列,从这里我们
看不出来区别
看下面的代码可以看出:
1、StringBuffe方法前都加了synchronized所以第一个区别就是StringBuffer是线程安全的,适合多线程环境。
StringBuffer源码
@Override
public synchronized int length() {
return count;
}
@Override
public synchronized int capacity() {
return value.length;
}
@Override
public synchronized void ensureCapacity(int minimumCapacity) {
super.ensureCapacity(minimumCapacity);
}
/**
* @since 1.5
*/
@Override
public synchronized void trimToSize() {
super.trimToSize();
}
/**
* @throws IndexOutOfBoundsException {@inheritDoc}
* @see #length()
*/
@Override
public synchronized void setLength(int newLength) {
toStringCache = null;
super.setLength(newLength);
}
/**
* @throws IndexOutOfBoundsException {@inheritDoc}
* @see #length()
*/
@Override
public synchronized char charAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
return value[index];
}
StringBuilder的源码
@Override
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
/**
* Appends the specified {@code StringBuffer} to this sequence.
* <p>
* The characters of the {@code StringBuffer} argument are appended,
* in order, to this sequence, increasing the
* length of this sequence by the length of the argument.
* If {@code sb} is {@code null}, then the four characters
* {@code "null"} are appended to this sequence.
* <p>
* Let <i>n</i> be the length of this character sequence just prior to
* execution of the {@code append} 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}.
*
* @param sb the {@code StringBuffer} to append.
* @return a reference to this object.
*/
public StringBuilder append(StringBuffer sb) {
super.append(sb);
return this;
}
@Override
public StringBuilder append(CharSequence s) {
super.append(s);
return this;
}
/**
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
@Override
public StringBuilder append(CharSequence s, int start, int end) {
super.append(s, start, end);
return this;
}
2、
StringBuilder的包:
package java.lang;
StringBuffer的包:
package java.lang;
import java.util.Arrays;
从这句话可以看出:两个类都是属于lang下的,但是StringBuffer中导入了Arrays的
StringBuffer中多出有一个这样的属性
/**
* A cache of the last value returned by toString. Cleared
* whenever the StringBuffer is modified.
*/
private transient char[] toStringCache;
解释一下这个代码的意思:
注释的意思是:toString返回的最后一个值的缓冲,当StringBuffer被修改时清除
transient修饰的变量值不参与序列化。
这个不重要,既然看到这儿了,我们在看一下String的特殊之处:
来,上源码:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
精华全在上边了:
1、首先多实现了Comparable接口,没有实现AbstractStringBuilder
2、低层value数组不可变,那我们看一下StringBuffer和StringBuilder
abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* The value is used for character storage.
*/
char[] value;
这是另一个区别是String是不可变的。