String、StringBuilder和StringBuffer的区别
-
String是不可变的,StringBuilder和StringBuffer是可变的。
-
StringBuffer是线程安全的,StringBuffer是非线程安全的。
String的不可变性
String在Java中特别常用,相信很多人都看过他的源码,在JDK中,关于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
}
可以看到,String类是Final类型的,表示这个类不可以被继承。
其次,String中存储值的char[]也是被final修饰的,表示他也是不能被修改的。
所以,String是一个不可变对象。
不可变对象是在完全创建后其内部状态保持不变的对象。这就意味着,一旦对象被赋值给变量,我们既不能更新引用,也不能通过任何方式改变内部状态。
可是有人会疑惑,String为什么不可变,我的代码中经常改变String的值啊,如下:
String str = "abcd";
str = str.concat("ABCD");
这样操作,不就将原本"abcd"的字符串改变成了"ABCD"了么?
但是,虽然字符串内容看上去从"abcd"变成了"ABCD",但实际上,我们得到的已经是一个新的字符串了。
如上图,在堆中重新创建了一个"ABCD"的字符串,和"abcd"不是同一个对象。
所以,一旦一个String对象在内存(堆)中被创建出来,她就无法被修改。而且。String类的所有方法都没有改变字符串本身的值,都是返回了一个新的对象。
如果我们想要一个可修改的字符串,可以选择StringBuffer或者StringBuilder这两个代替String。