关于String、StringBuilder和StringBuffer的区别,首先我们要明确,由于String的不可更改特性,所有的直接对String类型对象进行修改都会创建新对象,效率十分低下。因此,为了方便字符串的修改,Java中提供了StringBuilder和StringBuffer类。而这三者的区别就在于:String的内容不可修改,后两者的内容可以修改。而后两者大部分功能都是相似的,区别就在于:StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作
字符串的不可变性
- String是一种不可变对象,字符串中的内容是不可改变。
String类在设计时就是不可改变的,String类实现描述中已经说明了
以下来自JDK1.8中String类的部分实现:
- 由此,可以看出:String类被final修饰,表明该类不能被继承。并且,String类中的字符实际保存在内部维护的value字符数组中,value被修饰符final修饰,表明value自身的值不能改变,即不能引用其它字符数组,但是其引用空间中的内容可以修改。
【注】:字符串不可变因为其内部保存字符的数组被final修饰了,因此不能改变。这种说法是错误的,不是因为String类自身,或者其内部value被final修饰而不能被修改。
final修饰类表明该类不想被继承,final修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内容是可以修改的。
- 由于String类是不能修改的,因此所有的修改都会创建新对象 (我们在进行字符串修改时,应尽量避免直接对String类型对象进行修改,这种做法效率十分低下 )
StringBuilder和StringBuffer
由于String的不可更改特性,为了方便字符串的修改,Java中提供了内容可以修改的StringBuilder和StringBuffer类。这两个类大部分功能是相同的,在此我们仅讲解与修改字符串相关内容。
以下来自JDK1.8中StringBuilder和StringBuffer类的部分实现:
- StringBuffer线程安全的使用synchronization修饰的方法,(synchronized:相当于锁),采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作。
- 因此,在单线程下推荐使用StringBuilder,效率较高,而StringBuffffer更推荐用于多线程。
public static void main(String[] args) {
//StringBuiler
StringBuilder stringBuilder = new StringBuilder("abc");
System.out.println(stringBuilder);
//不会产生临时变量
stringBuilder.append("123");
System.out.println("StringBuilder第一次: " + stringBuilder);
stringBuilder.append("123").append(999);//可以连续叠加
stringBuilder.append("cc1");
System.out.println("StringBuilder第二次: " + stringBuilder);
//StringBuffer
StringBuffer stringBuffer = new StringBuffer("abcc");
stringBuffer.append("aaaa");
System.out.println("StringBuffer第一次: " + stringBuffer);
stringBuffer.append("aaaa").append("666");
System.out.println("StringBuffer第二次: " + stringBuffer);
}
- 与最大的区别在于String的内容无法修改,而StringBuilder,和StringBuffer的内容可以修改。因此,在需要频繁下字符串的情况下考虑使用后者。