目錄
緩存
安全性
線程安全
hashCode緩存
性能
其實這個問題我們可以通過緩存、安全性、線程安全和性能幾個維度去解析。
緩存
字符串是Java最常用的數據結構,我們都知道字符串大量創建是非常耗費資源的,所以Java中就將String設計為帶有緩存的功能,可以大大節省堆空間。
JVM中專門開辟了一部分空間來存儲Java字符串,那就是字符串池。
通過字符串池,兩個內容相同的字符串變量,可以從池中指向同一個字符串對象,從而節省了關鍵的內存資源。
String s1 = "abc";
String s2 = "abc";
對于這個例子,s1和s2都表示"abc",所以他們會指向字符串池中的同一個字符串對象。
但是,之所以可以這么做,主要是因為字符串的不變性。試想一下,如果字符串是可變的,我們一旦修改了s1的內容,那必然導致s2的內容頁被動的改變了,這顯然不是我們想看到的。
安全性
字符串在Java應用程序中廣泛用于存儲敏感信息,如用戶名、密碼、連接url、網絡連接等。JVM類加載器在加載類時也廣泛地使用它。
因此,保護String類對于提升整個應用程序的安全性至關重要。
當我們在程序中傳遞一個字符串的時候,如果這個字符串的內容是不可變的,那么我們就可以相信這個字符串中的內容。
但是,如果是可變的,那么這個字符串內容就可能隨時都被修改。那么這個字符串內容就完全不可信了。
線程安全
不可變會自動使字符串成為線程安全的,因為當從多個線程訪問它們時,它們不會被更改。
因此,一般來說,不可變對象可以在同時運行的多個線程之間共享。它們也是線程安全的,因為如果線程更改了值,那么將在字符串池中創建一個新的字符串,而不是修改相同的值。因此,字符串對于多線程來說是線程安全的。
hashCode緩存
由于字符串對象被廣泛地用作數據結構,它們也被廣泛地用于哈希實現,如HashMap、HashTable、HashSet等。在對這些散列實現進行操作時,經常調用hashCode()方法。
不可變性保證了字符串的值不會改變。因此,hashCode()方法在String類中被重寫,以方便緩存,這樣在第一次hashCode()調用期間計算和緩存散列,并從那時起返回相同的值。
性能
前面提到了字符串池、hashCode緩存等都是提升性能的體現。