String類為什么是不可變的


String類為啥是final的?

我們找到string的jdk源碼

 

 

 1.看到String類被final修飾。這里你就要說出被final修飾的類不能被繼承,方法不能被重寫,變量不能被修改。

2.看到final修飾的char[]代表了被存儲的數據不可更改性。但是:雖然final代表了不可變,但僅僅是引用地址不可變,並不代表了數組本身不會變,請看下面圖片

上圖說明:數組中的值發生了改變。

 

 

 

 上圖說明:無論如何修改,數組的地址值不會改變。

綜上:所以在這里只有final修飾是不能確保string的不可變性。還需要privite修飾。才能確保不可變性。

  • 因為字符串是不可變的,所以是多線程安全的,同一個字符串實例可以被多個線程共享。這樣便不用因為線程安全問題而使用同步。字符串自己便是線程安全的。
  •  因為字符串是不可變的,所以在它創建的時候HashCode就被緩存了,不需要重新計算。這就使得字符串很適合作為Map中的鍵,字符串的處理速度要快過其它的鍵對象。這就是HashMap中的鍵往往都使用字符串。

除了 String 類,系統類庫中還提供了一些其他的不可變類,基本類型的包裝類、BigInteger、BigDecimal等等。這些不可變類比可變類更加易於設計、實現和使用,不容易出錯且更加安全。另外,要記住並不僅僅是靠一個 final 關鍵字來實現不可變的,更多的是靠類內部的具體實現細節。


String真的不可變嗎?

 
綜上所述, String 的確是個不可變類,但是真的沒有辦法改變 String 對象的值嗎?答案肯定是否定的,反射機制可以做到很多平常做不到的事情。
String str = "123";
System.out.println(str);
Field field = String.class.getDeclaredField("value");
field.setAccessible(true);
char[] value = (char[]) field.get(str);
value[1] = '3';


執行結果:
123
133
很顯然,通過反射可以破壞 String 的不可變性。

 

參考:https://blog.csdn.net/weixin_44946052/article/details/89409188

https://www.jianshu.com/p/9c7f5daac283

https://segmentfault.com/a/1190000009914328


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM