String、StringBuffer、StringBuilder的区别
String:
String类是不可变的,对String类的任何改变,都是返回一个新的String类对象。即一旦一个String对象被创建以后,包含在这个对象中的字符序列是不可改变的,直至这个对象被垃圾回收。例如:
String a = "123";
a = "456";
// 打印出来的a为456
System.out.println(a)
//打印出来的a是456
在重新赋值这个过程中,String类不是对原来堆中实例进行重新赋值,而是生成了新的实例对象,并且指向了"456"这个字符串,a则指向了新生成的实例对象,之前的实例对象仍然存在,如果没有被再次引用的话,这个实例对象和"123"就会被垃圾回收。
String是被final修饰的,所以是不可被继承的。在下面的源码中可以看到源码中有两个属性值,value和hash,其中value是一个char数组,被final所修饰,没错,这是String是字符串常量的原因。value作为一个属性被final修饰符合final用法的第一条,因此value值不能改变,而String实际是由value值决定的,因此String值不能改变。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
StringBuffer:
StringBuffer对象代表一个字符序列可变的字符串,当一个StringBuffer被创建以后,通过StringBuffer提供的append()、insert()、reverse()、setCharAt()等方法可以改变这个字符串对象的字符序列。一旦通过StringBuffer生成了最终想要的字符串,就可以通过调用它的toString()方法将其转换为一个String对象。
StringBuffer b = new StringBuffer("123");
b.append("456");
// b打印结果为:123456
System.out.println(b);
StringBuffer类中的方法都添加了synchronized关键字,即给这个方法加了一个锁,用来保证线程安全。如下图所示:
StringBuilder:
StringBuilder类也可以代表可变字符串对象,实际上,StringBuilder和StringBuffer基本相似,两个类的构造器和方法也基本相同,不同的是:StringBuffer是线程安全的,而StringBuilder则没有实现线程安全功能,所以性能略高。如下图所以,StringBuilder是没有使用synchronized的
总结:
1.String是不可变的,每次重新赋值都会生成新的对象。
2.StringBuffer和StringBuilder是可变的,不需要生成新的对象。
3.三者执行速度:StringBuilder>StringBuffer>String
4.StringBuffer是线程安全的,StringBuilder是线程不安全的。