Java中String爲什麼被設計成immutable(不可修改的)/final

     String是Java中的一個immutable類。immutable類意味着該類的實例將無法被修改。該實例中的所有信息在其被創建時就已經被完全初始化,同時之後也無法再作修改。對於immutable類而言,其有很多優點。
1)字符串常量池的要求
    字符串常量池一個方法區中一個特殊存儲區域。當一個String被創建,並且該String在常量池中已經存在,則這個已經存在的String常量引用將會被返回給該String,而不需要再重新創建一個新的String實例。
    下面這段代碼在堆中只會創建一個String實例:
String string1 = "abcd";
String string2 = "abcd";
    這裏是內存存儲的大致示意圖:
    
  
     如果String不是immutable的,改變其中一個String的引用,將會造成另一個變量引用出錯。

2)HashCode
    String類型的hashCode 在Java中是普遍存在的(見Java String的hashCode實現),如HashMap,Object等。immutable可以保證hashcode始終相同,因此可以不用擔心key值的改變,方便鍵值對的存儲。immutable,這也意味着不需要每次使用時都對hashcode進行計算,提高了運行效率。
    在String類中,有如下代碼:
private int hash;//this is used to cache hash code.

3)有利於其他一些類的使用
    考慮下面的代碼:
HashSet<String> set = new HashSet<String>();
set.add(new String("a"));
set.add(new String("b"));
set.add(new String("c"));
 
for(String a: set)
	a.value = "a";
    在這個示例中,如果String是可修改的,它的value可以被任意修改,那麼這將未被set被設計的初衷(因爲set中是不允許有重複元素出現的,String若可修改,則會造成該情況發生)。(注:前面代碼僅是爲了演示,真正的String類型中並沒有value變量)。

4)安全性
    String在Java類中廣泛地作爲參數進行使用,比如,網絡連接,打開文件等。如果String可修改,一個connection或者file將會被改變,而這將有可能造成嚴重的後果。同時mutable的String類同樣也會對反射(Reflection)造成嚴重的後果,因爲其使用的參數也都是String類型的。
boolean connect(string s){
    if (!isSecure(s)) { 
throw new SecurityException(); 
}
    //here will cause problem, if s is changed before this by using other references.    
    causeProblem(s);
}

5)Immutable類具有多線程安全性
    因爲immutable實例不可被修改,則它們就能夠在多線程中實現安全共享,這在實現多線程同步中是很重要的。

6)String設計成final,也有利於Java將其優化成內聯函數,提高虛擬機效率。
    總而言之,將String設計成immutable是處於效率和安全性方面的考慮,這也是immutable類在使用中的共通優點。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章