1、数据可变和不可变
1. String 底层使用一个不可变的字符数组 private final char value[]; 所以它内容不可变。每次对存放进String当中的字符串进行更改的时候,都会生成一个新的String对象,然后指针指向该对象(虽然Java不承认自己有指针这回事),当没有引用指向对象过多的时候 ,GC就会对其进行清理,这个时候性能就会有所降低。
2. StringBuffer 和 StringBuilder 都继承了 AbstractStringBuilder 底层使用的是可变字符数组: char[] value;
2、线程安全
StringBuilder 是线程不安全的,效率较高;而 StringBuffer 是线程安全的,效率较低。 通过他们的 append() 方法来看, StringBuffer 是有同步锁,而 StringBuilder 没有。
@Override
public synchronized StringBuffer append(Object obj) {
toStringCache = null;
super.append(String.valueOf(obj));
return this;
}
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
3、 相同点
StringBuilder 与 StringBuffer 有公共父类 AbstractStringBuilder 。
最后,一般操作可变字符串速度: StringBuilder > StringBuffer > String 。
某些特殊的情况下,使用String 并不会比StringBuffer慢!!!
例如 :
String str = "String1" + "String2";
StringBuffer sb = new StringBuffer(); sb.append("String1").append("String2");
在这里的String str = "String1" + "String2" 被编译器在编译时优化后,相当于直接定义了一个”String1String2”的字符串。这说明javac编译可以对字符串常量直接相加的表达式进行优化,不必要等到运行期再去进行加法运算处理,而是在编译时去掉其中的加号,直接将其编译成一个常量相连的结果。
4、String 类的常用方法
indexOf():返回指定字符的索引。
charAt():返回指定索引处的字符。
replace():字符串替换。
trim():去除字符串两端空白。
split():分割字符串,返回一个分割后的字符串数组。
getBytes():返回字符串的 byte 类型数组。
length():返回字符串长度。
toLowerCase():将字符串转成小写字母。
toUpperCase():将字符串转成大写字符。
substring():截取字符串。
equals():字符串比较。