String 是字符串常量(线程安全);
StringBuffer(线程安全), StringBuilder(非线程安全) 是字符串变量。
String、StringBuilder、StringBuffer类定义
它们三个类都被final说明这三个都是不可变类。
StringBuilder、StringBuffer这两个类都继承了AbstractStringBuilder。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
String、StringBuilder、StringBuffer创建
String类中包含一个不可变的char数组用来存放字符串
/** 这个value被用于存放char变量 */
private final char value[];
public String() {
this.value = "".value;
}
StringBuilder和SpringBuffer都使用父类的构造函数进行初始化,
public StringBuilder() {
super(16);
}
public StringBuffer() {
super(16);
}
父类的构造方法,
可以看到和String类的区别是value类没有使用final类去修饰,所以在高并发下对value的操作是不安全的。
char[] value;
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
String、StringBuilder、StringBuffer的操作
String的添加操作只需要使用+号连接就行
StringBuilder、StringBuffer则需要使用append方法进行操作。
但是String使用+号操作,在jvm进行编译过后也是使用StringBuilder去进行连接操作的。
StringBuilder、StringBuffer他们两的append方法区别就在于StringBuilder没有同步锁,而StringBuffer加了同步锁。
他们同时都是调用父类的方法进行实现。
父类的append类似于Arraylist的add,在超出一定容量之后都是要对value数组进行扩容
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
总结
大部分情况下效率StringBuilder > StringBuffer > String
StringBuilder 和 StringBuffer在创建字符串对其进行操作的适合都是使用的统一个对象,而String的value是不可变的数组所以每次需要构造String的适合都是需要new出一个对象,再把这个对象引用过去,效率会很低下。