在日常的学习中,我们不可避免的需要接触字符串相关的知识,但是对于初学者而言可能接触的更多的是String类型,对于StringBuffer、StringBuilder的存在可能还不是很清楚,而在面试中,关于这三者的联系与区别也基本是必问的知识点。
String 类型
对于String的源码查看我们可以知道,这个类的底层实现原理就是一个final型的字符数组。
/** The value is used for character storage. */
private final char value[];
通过这个final关键字我们可以知道,String具有不可变性这个特性以及不可继承性,主要是为了提高安全性。还有值得注意的是String的不可变性指的是引用地址的值不可变。而不是引用地址不可变。
还有就是值得注意的是在创建String对象的时候尽量不要使用new 关键字,因为String对象具有常量池优化,如果我们创建的String具有相同的字符串,那么后面创建的对象将会直接使用这个缓存,也就是将引用指向一开始创建这个字符串的引用地址。从而节省空间。
StringBuffer类型
受制于String的不可变性,我们有时候又恰好需要可变的字符串,于是StringBuffer诞生了。StringBuffer继承了AbstractStringBuilder并且实现了Serializable,意味着StringBuffer可以序列化。
而StringBuffer是可以随意变换的对象,使用该对象可以较好的完成字符串的添加以及变换。
还有就是StringBuffer的所有方法添加了synchronized ,意味着这个类型是线程安全的。不会存在并发问题的产生
public synchronized int length() {
return count;
}
@Override
public synchronized int capacity() {
return value.length;
}
@Override
public synchronized void ensureCapacity(int minimumCapacity) {
super.ensureCapacity(minimumCapacity);
}
/**
* @since 1.5
*/
@Override
public synchronized void trimToSize() {
super.trimToSize();
}
/**
* @throws IndexOutOfBoundsException {@inheritDoc}
* @see #length()
*/
@Override
public synchronized void setLength(int newLength) {
toStringCache = null;
super.setLength(newLength);
}
StringBuilder类型
StringBillder在使用的方法上基本与StringBuffer一样。但是StringBillder的所有方法上没有添加synchronized 关键字,意味在多线程环境下使用StringBuilder是线程不安全的。StringBillder的所有方法返回值都是StringBuilder,可以认为StringBuilder的方法都是在对自身进行操作。在有特别需要的情况下可以重写该StringBuilder类方法添加synchronized 即可。
总结
如果是操作少量数据以及字符串变化不大的话,可以使用String即可
如果在单线程情况操作字符串,应该使用StringBuilder
如果在多线程情况操作字符串,应该使用StringBuffer
不考虑安全的话性能上排名:StringBuilder>StringBuffer>String
写到这里基本上这三者基本上都了解清楚了。好啦。拜拜!