Java String為什麼是不可變類,StringBuffer與StringBuilder區別
阿新 • • 發佈:2019-02-06
熟悉Java的都知道String類是不可變,但String類為什麼設計成不可變類,如何做到不可變沒有仔細想過。
String為什麼設計成不可變類?
1.符合Java字串池的設計方式。String s1="abc";
String s2="abc";
Java通過字串池的設計方式節省記憶體空間,如上面一段程式碼只會生成一個物件放在常量池當中。s1和s2都指向這個物件,如果String類可變,通過s1這個引用就可以修改這個物件,那其他引用就會受影響。
2.安全性。
JDK提供的眾多API當中,大多的引數都是String型別,如類載入函式,資料庫的連線,Sql語句,Socket的引數等。如果String類可以被修改就會造成安全漏洞。而且多執行緒情況下,String類資料也可以保護資料不被其他執行緒修改。String怎麼實現不可變?
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
private final char value[];
從String類的原始碼中可以看到,String是通過char value[]儲存字元的。而且宣告為private final,並且不提供我們寫value的介面。所以String類不能夠修改。
(其實String類並不是不能修改,可以通過java的反射機制,獲取到string物件的class物件,把value屬性private修改為可訪問型別,然後就可以直接訪問物件value屬性了)//StringBuffer類的原始碼 public synchronized void ensureCapacity(int minimumCapacity) { if (minimumCapacity > value.length) { expandCapacity(minimumCapacity); } } /** * @since 1.5 */ public synchronized void trimToSize() { super.trimToSize(); } /** * @throws IndexOutOfBoundsException {@inheritDoc} * @see #length() */ public synchronized void setLength(int newLength) { super.setLength(newLength); } /** * @throws IndexOutOfBoundsException {@inheritDoc} * @see #length() */ public synchronized char charAt(int index) { if ((index < 0) || (index >= count)) throw new StringIndexOutOfBoundsException(index); return value[index]; }