摘要:我們都知道中的類的設計是不可變的,來看下類的源碼。其值也就是對字符數組的封裝,即,其值被定義成的,說明不能通過外界修改,即不可變。真的不可變嗎來看下面這個例子。所以說,這里的字符串并不是可變,只是變更了字符串引用。
我們都知道 Java 中的 String 類的設計是不可變的,來看下 String 類的源碼。
public final class String implements java.io.Serializable, Comparable, 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 不能被繼承。其值 value 也就是對字符數組的封裝,即 char[],其值被定義成 private final 的,說明不能通過外界修改,即不可變。
String 真的 "不可變 " 嗎?來看下面這個例子。
String str = "Python"; System.out.println(str); // Python str = "Java"; System.out.println(str); // Java str = str.substring(1); System.out.println(str); // ava
你有可能會問:str 不是由 Python 變成 Java 了嗎?然后通過 substring 方法變成 ava 了嗎?
這其實是初學者的一個誤區,從上面看 String 的結構可以得知字符串是由字符數組構成的,str 只是一個引用而已,第一次引用了 "Python",后面變成了 "Java",而 substring 也是用 Arrays.copyOfRange 方法重新復制字符數組構造了一個新的字符串。
所以說,這里的字符串并不是可變,只是變更了字符串引用。
關于 substring 在 JDK 各個版本的差異可以看這篇文章《注意:字符串substring方法在jkd6,7,8中的差異》,也可以去看 substring 的各個版本的源碼。
String 真的真的真的 "不可變 " 嗎?上面的例子肯定是不可變的,下面這個就尷尬了。
String str = "Hello Python"; System.out.println(str); // Hello Python Field field = String.class.getDeclaredField("value"); field.setAccessible(true); char[] value = (char[])field.get(str); value[6] = "J"; value[7] = "a"; value[8] = "v"; value[9] = "a"; value[10] = "!"; value[11] = "!"; System.out.println(str); // Hello Java!!
通過反射,我們改變了底層的字符數組的值,實現了字符串的 “不可變” 性,這是一種騷操作,不建議這么使用,違反了 Java 對 String 類的不可變設計原則,會造成一些安全問題。
是不是又漲姿勢了?分享給你的朋友們吧!更多干貨推薦
1.史上最強 Java 中高級面試題整理
2.史上最強 Spring Boot & Cloud 教程整理
3.史上最強架構設計分布式技術干貨整理
更多請掃描下方的二維碼關注我們的微信公眾號,干貨每日推送!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/77303.html
摘要:性能當字符串是不可變時,字符串常量池才有意義。字符串常量池的出現,可以減少創建相同字面量的字符串,讓不同的引用指向池中同一個字符串,為運行時節約很多的堆內存。 在學習Java的過程中,我們會被告知 String 被設計成不可變的類型。為什么 String 會被 Java 開發者有如此特殊的對待?他們的設計意圖和設計理念到底是什么?因此,我帶著以下三個問題,對 String 進行剖析: ...
摘要:方法可接收兩個參數,第一個參數是分隔符,即用來分隔字符串的字符,默認是所有的空字符,包括空格換行制表符等。拆分過程會消耗分隔符,所以拆分結果中不包含分隔符。 正如《你真的知道Python的字符串是什么嗎?》所寫,Python 中字符串是由 Uniocde 編碼的字符組成的不可變序列,它具備與其它序列共有的一些操作,例如判斷元素是否存在、拼接序列、切片操作、求長度、求最值、求元素的索引位...
摘要:方法可接收兩個參數,第一個參數是分隔符,即用來分隔字符串的字符,默認是所有的空字符,包括空格換行制表符等。拆分過程會消耗分隔符,所以拆分結果中不包含分隔符。 正如《你真的知道Python的字符串是什么嗎?》所寫,Python 中字符串是由 Uniocde 編碼的字符組成的不可變序列,它具備與其它序列共有的一些操作,例如判斷元素是否存在、拼接序列、切片操作、求長度、求最值、求元素的索引位...
閱讀 2520·2023-04-25 17:37
閱讀 1203·2021-11-24 10:29
閱讀 3710·2021-09-09 11:57
閱讀 705·2021-08-10 09:41
閱讀 2258·2019-08-30 15:55
閱讀 2823·2019-08-30 15:54
閱讀 1953·2019-08-30 15:53
閱讀 908·2019-08-30 15:43