中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java字符串的不可變是什么意思

發布時間:2021-07-07 14:31:23 來源:億速云 閱讀:257 作者:chen 欄目:大數據

這篇文章主要介紹“Java字符串的不可變是什么意思”,在日常操作中,相信很多人在Java字符串的不可變是什么意思問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java字符串的不可變是什么意思”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

前言

在 Java 開發中 String (字符串)對象是我們使用最頻繁的對象,也是很重要的對象。正是使用得如此頻繁,String 在實現層面上不斷進行優化,從 Java6 到 Java7,再到 Java9 的新實現 ,都是為了提升 String 對象的性能,而其中不變的是 String 所生俱來的特性:不可變。本文主要聊一聊 String 的不可變,以及為什么存在的。

什么是 String 的不可變

首先我們先來看下什么是不可變對象:一旦對象被創建并初始化后,內部的狀態數據就會保持不變。查看 JDK 源碼中的 String 類,可以看到類本身被 final 修飾,并且內部的大部分屬性都是 final 修飾的,除了字段 hash 是通過字符串內容計算并緩存起來的。這樣的行為讓 String 類無法被擴展,內部屬性也無法被修改。

接著我們再來用畫圖的形式來說明下 String 的不可變性。

通常我們初始化字符串都是以下形式:Java字符串的不可變是什么意思

String 類型的引用變量 a 保留了一個字符串對象 string 的引用,就如同下圖所示,箭頭則表示了變量 a 與真正 String 對象的引用關系。

Java字符串的不可變是什么意思

Java字符串的不可變是什么意思

再通過上述代碼,我們將變量 a 賦值給變量 b ,變量 b 也存儲了字符串對象 string的引用,它們指向的是同一個對象。

Java字符串的不可變是什么意思

當我們嘗試對變量 a 重新賦值,看下對變量 b 會不會有影響呢

Java字符串的不可變是什么意思

想必小伙伴一看就知道,打印的結果肯定是 string2,string,同樣用畫圖的方式展示這兩個變量與字符串對象的引用關系。

Java字符串的不可變是什么意思

將變量 a 重新賦值后,保存了新的引用,而不是直接在原有的字符串對象上進行數據改變,同時變量 b 仍然存的是對象 string 的引用,變量 ab 兩者相互獨立,不影響,這也正是說明了 String 對象的不可變。

在這里初認 Java 的小伙伴還可能會有些困惑:對一個String對象 a 賦值 string,然后又讓 a 值為 string2,這個時候a的值變成 了string2, a 的值改變了,為什么還說 String 對象不可變呢。

其實問題也很簡單,這里的 a 只是存儲 String 對象的引用,并不是對象本身,a 存儲的是指向對象所在內存的地址引用罷了,當第二次賦值時,a 引用指向了對象 string2的內存地址,而對象 string2 是重新創建的,之前的 string 對象仍在內存中,并且由變量 b 引用著。

除此之外,String 類的返回 String 對象的方法不會改變自身,都是返回一個新的 String 對象來實現,比如 concatreplacesubstring 等等。

Java字符串的不可變是什么意思

為什么 String 需要不可變

聊完什么是 String 的不可變后,接下來我們再說說 String 為什么需要不可變呢,又有什么好處呢?

字符串常量池的實現

在Java中,我們通常有兩種方式創建字符串對象,一種是通過字符串字面量方式創建,就如上文的代碼,另外一種就是通過 new 方式去創建,如 String c = new String("string 3"); 而兩者區別就在于通過字符串字面量的方式創建時,JVM 會現在字符串池中檢查字符串內容是否已經存在,如果存在就會直接返回對應的引用,而不是再次分配內存進行創建,如果不存在就會分配在內存中創建的同時將字符串數據緩存在字符串池中,便于重用。正是是由于字符串的不可變,同樣的字符串內容可以讓 JVM 可以減少額外的內存分配操作,直接使用在字符串池中字符串對象即可,對性能提升和內存節省都大有好處。

Java字符串的不可變是什么意思

關于字符串池,這里稍微簡單介紹一下:**Java 的字符串池屬于 JVM 專門給指定的特殊內存區域,用來存儲字符串字面量。**在 Java 7 之前,分配于 JVM 的方法區內,屬于常量池的一部分;而 Java7 之后字符串池被移至堆內存進行管理,這樣的好處就是允許被 JVM 進行垃圾回收操作,將未被引用的字符串所占內存即使回收,以此節省內存。

Hashcode 緩存

字符串作為基礎的數據結構,大量地應用在一些集合容器之中,尤其是一些散列集合,在散列集合中,存放元素都要根據對象的 hashCode() 方法來確定元素的位置。由于字符串 hashcode 屬性不會變更,保證了唯一性,使得類似 HashMap,HashSet 等容器才能實現相應的緩存功能。由于 String 的不可變,避免重復計算 hashcode,只有使用緩存的 hashcode 即可,這樣一來大大提高了在散列集合中使用 String 對象的性能。

線程安全

在多線程中,只有不變的對象和值是線程安全的,可以在多個線程中共享數據。由于 String 天然的不可變,當一個線程”修改“了字符串的值,只會產生一個新的字符串對象,不會對其他線程的訪問產生副作用,訪問的都是同樣的字符串數據,不需要任何同步操作。

安全性

由于字符串無論在任何 Java 系統中都廣泛使用,會用來存儲敏感信息,如賬號,密碼,網絡路徑,文件處理等場景里,保證字符串 String 類的安全性就尤為重要了,如果字符串是可變的,容易被篡改,那我們就無法保證使用字符串進行操作時,它是安全的,很有可能出現 SQL 注入,訪問危險文件等操作。

結語

通過本文,我們介紹 String 是不可變的,可以將它們的引用可以被當作一個普通的變量來使用,無論是在方法間,還是線程間傳遞它們,都不用擔心它指向的實際 String 對象發生改變,并且不可變的特性也在語言層面和程序層面上帶了許多好處,在平常編程實踐中我們也應該多學習效仿,用 James Gosling,Java之父的話說就是”我會盡可能地使用不可變對象“。

到此,關于“Java字符串的不可變是什么意思”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

平塘县| 融水| 汉中市| 台前县| 那曲县| 邢台市| 渑池县| 新昌县| 融水| 兴山县| 巴林右旗| 叶城县| 昔阳县| 洛宁县| 武定县| 南陵县| 宁明县| 易门县| 吴桥县| 吉安市| 咸宁市| 德昌县| 兴义市| 高雄市| 昭苏县| 玉龙| 大关县| 屏东市| 清原| 西乌珠穆沁旗| 澄江县| 景德镇市| 卢氏县| 永靖县| 团风县| 兴化市| 财经| 文水县| 罗山县| 武清区| 津市市|