String
文档中对String描述
源码中是维护了一个final定义的数组,初始化后就不可被修改;因此String字符串是不可以改变的。
StringBuffer
文档描述StringBuffer是一种可以修改的“String字符串缓冲区”
继承AbstractStringBuilder抽象类
AbstractStringBuilder源码中成员变量与构造函数(空构造函数就不提了)
/**
* The value is used for character storage.
*/
char[] value;
/**
* The count is the number of characters used.
*/
int count;
/**
/**
* Creates an AbstractStringBuilder of the specified capacity.
*/
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
当给StringBuffer初始化时如果传一个初始长度的话,StringBuffer会调用父类的构造方法,给value[]数组初始化,count代表sbf的已使用的长度(即已有字符的个数)
StringBuffer中的成员变量与构造方法,会给一个初始的数组长度16.
注意:如果构造函数传入null的话 会出现空指针异常。
/**
* A cache of the last value returned by toString. Cleared
* whenever the StringBuffer is modified.
* toString返回的最后一个值的缓存。每当修改StringBuffer时清除。
*/
private transient char[] toStringCache;
public StringBuffer() {
super(16);
}
/**
* Constructs a string buffer with no characters in it and
* the specified initial capacity.
*
* @param capacity the initial capacity.
* @exception NegativeArraySizeException if the {@code capacity}
* argument is less than {@code 0}.
*/
public StringBuffer(int capacity) {
super(capacity);
}
/**
* Constructs a string buffer initialized to the contents of the
* specified string. The initial capacity of the string buffer is
* {@code 16} plus the length of the string argument.
*
* @param str the initial contents of the buffer.
*/
public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}
toStringCache的作用是缓存最近一次toString()方法的值,在对SBF更改的时候,这个字段就会清空,在下一次toString()会将这个变量重新初始化。个人觉得这个缓冲区的作用场景是进行大量的重复的toString()时使用,平衡一下与StringBuilder的速度差距。
如下源码
@Override
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
}
而为什么StringBuffer是线程安全的是因为类中的很多方法都用synchronized关键字修饰,因此它的速度不是很快
StringBuilder
StringBuilder与StringBuffer相同也是一个可变的字符序列,同样继承自AbstractStringBuilder。
而不同的是StringBuilder没有toStringCache缓冲区域。还有就是没有synchronized关键字,不是线程安全的,速度很快。
String、StringBuffer、StringBuilder的区别
- 这三个类都是final类,不可被继承,后两者继承的类与实现的接口都一致,继承AbstractStringBuilder
- 运行速度:String<String<StringBuilder
- String,当在“abc”后面加上"de"时,需要先为"de"开辟空间,再为"abcde"开辟空间,速度非常的慢
- 因为StringBuffer中的很多方法都用synchronized关键字修饰,所以每次判断锁,所以比StringBuilde慢
- 线程安全:String不可以被更改,肯定线程安全。StringBuffer是线程安全的
- 使用场景
- String:少量的字符串操作
- StringBuffer:多线程下大量的字符串缓冲区的操作
- StringBuilder:单线程下大量字符串缓冲区的操作
推荐一首杨乃文的《未接电话》,很好听