简析String 、StringBuffer和StringBuilder
- 简述String
String类,即字符串类,具有不可变性,具体体现在:每次对String对象进行改变时,会生成一个临时的新的String对象,然后将指针指向新的对象;例如,String 对象的连接操作。
System.out.println("abc");
String cde = "cde";
String abcde = "abc" + cde;
System.out.println(abcde );
String对象的连接(concatenation) 操作内部使用了StringBuilder(或者StringBuffer)类和其append初始化方法。根据JAVA字节码,上述代码实际步骤如下:
1.产生StringBuilder临时变量,并使用字符串“abc”初始化;
2.使用StringBuilder类的append方法连接字符串“abc”;
3.临时StringBuilder变量调用toString()方法返回。
String abcde = new StringBuilder("abc").append("cde").toString();
因每次生成对象对系统性能有一定的影响,因此,对于频繁改变的字符串建议不要用String类,效率会比较低。
- StringBuilder vs StringBuffer
StringBuilder是易变的,但是非线程安全的,适用于单线程;StringBuilder类中最基本的方法就是insert()、append()和toString()方法。
StringBuffer是易变的,线程安全的。因为StringBuffer中变化的操作均用synchronized同步锁保证线程安全。例如StringBuffer中JAVA源码如下:
@Override
public synchronized StringBuffer append(double d) {
toStringCache = null;
super.append(d);
return this;
}
StringBuffer就像一块字符串缓冲区,多个线程可以访问,通过insert()和append()方法调用可以修改字符串。
- 速度比较**
StringBuffer > StringBuilder >String
StringBuilder 性能更优在文中第一个例子中已做说明;
StringBuilder和StringBuffer性能的比较见源码:
StringBuilder的append方法:
@Override
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
StringBuffer中的append方法的执行需要满足一定条件,即等待该Buffer synchronized 锁成功后,才可以对该Buffer进行修改。加锁会带来性能上的损耗。