- String、StringBuffer、StringBuilder类的定义
- 区别一
- String、StringBuffer、StringBuilder的构造函数
- 区别二
- StringBuffer、StringBuilder的部分方法
- 区别三
- 总结
我们首先来分析以下String、StringBuffer、StringBuilder三个类在源码中的定义:
- String
public final class String
implements java.io.Serializable, Comparable, CharSequence
public interface CharSequence
- StringBuffer
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
abstract class AbstractStringBuilder implements Appendable, CharSequence
public interface Appendable
- StringBuilder
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
可见,String、StringBuffer、StringBuilder都实现了Serializable(序列化)接口,其他的继承实现关系如下图所示:
下面对上图中涉及到的一些类做一个解释:
| 类名 | 解释 |
|---|---|
| AbstractStringBuilder | 这个抽象类是StringBuilder和StringBuffer的直接父类,实现可修改的字符串。在任何时间点,它都包含一些特定的字符序列,但是序列的长度和内容可以通过某些方法调用来更改。 |
| Appendable接口 | 定义字符串添加的’规则’(append()方法) |
| CharSequence接口 | 是一个可读的char值序列。这接口提供了对多种不同类型数据的统一只读访问char序列。 |
由于StringBuilder和StringBuffer继承了AbstractStringBuilder ,所以StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象;而String的值是不可变的,每次对String的操作都会生成新的String对象,这样不仅效率低下,而且大量浪费有限的内存空间。
String、StringBuffer、StringBuilder的构造函数- String
参考:从源码分析String类中的常用方法 - StringBuffer
public StringBuffer() {
super(16);
}
public StringBuffer(int capacity) {
super(capacity);
}
public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}
public StringBuffer(CharSequence seq) {
this(seq.length() + 16);
append(seq);
}
- StringBuilder
public StringBuilder() {
super(16);
}
public StringBuilder(int capacity) {
super(capacity);
}
public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}
public StringBuilder(CharSequence seq) {
this(seq.length() + 16);
append(seq);
}
区别二
每个StringBuffer、StringBuilder对象都有一定的缓冲区容量(初始大小为16),当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量。
StringBuffer、StringBuilder的部分方法- 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);
}
@Override
public synchronized void trimToSize() {
super.trimToSize();
}
@Override
public synchronized void setLength(int newLength) {
toStringCache = null;
super.setLength(newLength);
}
@Override
public synchronized char charAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
return value[index];
}
@Override
public synchronized int codePointAt(int index) {
return super.codePointAt(index);
}
@Override
public synchronized int codePointBefore(int index) {
return super.codePointBefore(index);
}
@Override
public synchronized int codePointCount(int beginIndex, int endIndex) {
return super.codePointCount(beginIndex, endIndex);
}
- StringBuilder
@Override
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
@Override
public StringBuilder delete(int start, int end) {
super.delete(start, end);
return this;
}
@Override
public StringBuilder deleteCharAt(int index) {
super.deleteCharAt(index);
return this;
}
@Override
public StringBuilder replace(int start, int end, String str) {
super.replace(start, end, str);
return this;
}
@Override
public StringBuilder insert(int index, char[] str, int offset,
int len)
{
super.insert(index, str, offset, len);
return this;
}
@Override
public int indexOf(String str) {
return super.indexOf(str);
}
@Override
public StringBuilder reverse() {
super.reverse();
return this;
}
@Override
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
s.defaultWriteObject();
s.writeInt(count);
s.writeObject(value);
}
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
count = s.readInt();
value = (char[]) s.readObject();
}
区别三
StringBuffer中的方法都有synchronized关键字修饰,而StringBuilder没有,所以StringBuffer线程安全,而StringBuilder线程不安全。
总结| String | StringBuffer | StringBuilder |
|---|---|---|
| String的值是不可变的,每次对String的操作都会生成新的String对象,这样不仅效率低下,而且大量浪费有限的内存空间 | StringBuffer类的对象能够被多次的修改,并且不产生新的未使用对象,有一定的缓冲区容量(初始大小为16),当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量。 | StringBuilder类的对象能够被多次的修改,并且不产生新的未使用对象,有一定的缓冲区容量(初始大小为16),当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量。 |
| 不可变类 | 可变类 | 可变类 |
| 线程安全 | 线程不安全 | |
| 多线程操作字符串 | 单线程操作字符串 |
StringBuilder提供一个与 StringBuffer 兼容的 API,但不保证同步。StringBuilder被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。



