String
String 是 Java 的不可变字符串类。使用 String 创建出来的字符串不可被改变,缺点是占用内存多,无用的字符串还是存在。
String a = "morning";
a = a + "king";
System.out.println(a);
我们的字符串常量池中会有三个字符串,分别是
- morning
- king
- morningking
被改变的是 a 的地址,内存被占用着。
StringBuffer 和 StringBuilder
使用StringBuffer 和 StringBuilder 创建的字符串是可变的。可以解决内存占用的问题。当然他们不是完美的,本身也有各自的问题。
StringBuffer 是线程安全的。这一点没有问题,但是他的运行速度要慢一些。
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
/**
* A cache of the last value returned by toString. Cleared
* whenever the StringBuffer is modified.
*/
private transient char[] toStringCache;
…………
//这里随便截取了几个方法
@Override
public synchronized void setCharAt(int index, char ch) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
toStringCache = null;
value[index] = ch;
}
@Override
public synchronized StringBuffer append(Object obj) {
toStringCache = null;
super.append(String.valueOf(obj));
return this;
}
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
在StringBuffer的源码里可以看到有一个缓冲数组,在内部的方法中,都要使用这个数组,对速度有影响。还有一点,方法都使用了 synchronized声明,加锁保证线程安全。
StringBuilder与StringBuffer对比就是速度快,线程不安全。
总结一下:
String 不可变,浪费空间
StringBuilder,可变,速度快,线程不安全
StringBuffer,可变,速度慢,线程安全
当然,不可变的 String 也是线程安全的。
早睡早起,good morning!