1.可变性
String:不可变StringBuffer:可变
StringBuilder:可变
String:内容不可变,
因为底层的value是使用final修饰的,final修饰则不可以被继承,所以String是一个不可变的类,每次修改String值的时候,都会创建一个新的对象
private final char[] value;
StringBuffer和StringBuilder:内容可变,
底层的value就是char [ ],StringBuffer和StringBuilder是可变的类,每次String的值变更时不会产生新的对象
char[] value;
2.安全性
String:线程安全
StringBuffer:线程安全
StringBuilder:线程不安全
String是一个不可变的类,所以是线程安全的;
StringBuffer类的每一个操作方法里都用了一个synchronized,这是一个同步关键字,所以是线程安全的;
StringBuilder不是线程安全的
3.性能
一般情况:String < StringBuffer < StringBuilder
String性能最低,因为String类不可变,每次对字符串操作(拼接、修改…)的时候都需要创建新的对象,分配新的内存;
当你定义一个String时,对象放到堆里面;
String str = "hello";
当你对String进行操作时,此时其实是在new一个新的String对象 ,放入jvm的堆里面,同时通过让jvm将原本堆中的对象清理掉;
str += " world";
String str=new String("hello world");
而StringBuffer和StringBuilder的性能都要比String的性能高,因为StringBuffer类和StringBuilder类都是可变的,字符串的值都可以直接被修改;
其中StringBuilder性能要比StringBuffer性能高一点,因为StringBuffer加了同步锁
可以通过实际的代码的运行比较String、StringBuffer、StringBuilderr的性能:
package training;
public class testSSS {
public static void main(String[] args) {
int n = 100000;
long t1 = System.currentTimeMillis();
String str = "";
for (int i = 0; i < n; i++) {
str += "hello-" + i;
}
System.out.println("t1:" + (System.currentTimeMillis() - t1));
long t2 = System.currentTimeMillis();
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < n; i++) {
stringBuffer.append("hello-" + i);
}
System.out.println("t2:" + (System.currentTimeMillis() - t2));
long t3 = System.currentTimeMillis();
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < n; i++) {
stringBuilder.append("hello-" + i);
}
System.out.println("t3:" + (System.currentTimeMillis() - t3));
}
}
运行结果
扩大n为10000000,单独测试StringBuffer和StringBuilder的性能
package training;
public class testSSS {
public static void main(String[] args) {
int n = 10000000;
// long t1 = System.currentTimeMillis();
// String str = "";
// for (int i = 0; i < n; i++) {
// str += "hello-" + i;
// }
// System.out.println("t1:" + (System.currentTimeMillis() - t1));
long t2 = System.currentTimeMillis();
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < n; i++) {
stringBuffer.append("hello-" + i);
}
System.out.println("t2:" + (System.currentTimeMillis() - t2));
long t3 = System.currentTimeMillis();
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < n; i++) {
stringBuilder.append("hello-" + i);
}
System.out.println("t3:" + (System.currentTimeMillis() - t3));
}
}
运行结果
4.存储方面
String存储在字符串常量池里面
而StringBuffer和StringBuilder存储在堆内存空间
5.补充
而StringBuffer和StringBuilder都是派生自AbstractStringBuilder抽象类
这个可以通过而StringBuffer类或StringBuilder类点击进入查看