String
打开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
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;
.............
}
可以看到String是一个被final修饰的类(不要按类上的final,应该看value[]字段,String的文章中提到过String的底层是一个char的数组),而被final修饰后是无法修改继承的(常量),所以其实你在更改String对象的值的时候并不是将他修改了,而是把当前对象附给新的对象然后JAVA虚拟机回收该对象
public class TestString {
public static void main(String[] args) {
String str="str";
//将str赋值给新的str然后回收之前的str对象
str=str+"a";
}
}
在操作大量字符串的时候难免会出现一个String对象的反复新建与回收,所以当涉及大量字符串的修改时String会降低程序的效率
StringBuffer
StringBuffer与String不同他的char字段并没有被final修饰,所以他本身是一个变量,所以在涉及大量字符串的修改时StringBuffer的效率比String更高,因为他不需要在操作大量字符串时去反复新建与回收对象。
当然在第一次声明一个字符串时,看不出StringBuffer的优势,因为新建并没有去改变String对象的值
public static void main(String[] args) {
String str="str";
StringBuffer stringBuffer=new StringBuffer("str");
}
StringBuilder
StringBuilder他的效率比StringBuffer更高,决定他效率更高的是他们的源码中:StringBuilder中没有锁,而在StringBuffer中有大量的锁(具体大家可以去看java源码),所以StringBuilder同时也应该尽量避免在多线程下使用,而StringBuffer不需要在意这个问题
总结
String:适用与少量字符串的操作的情景;
StringBuffer:适用于多线程下大量字符串操作的情景;
StringBuilder:适用于多线程下大量字符串操作的情景;
具体效率差别大家可以去用代码测试;