為什麼Java字符串是不可變對象?(3)

2020-11-23 51CTO

為什麼Java字符串是不可變對象?(3)

本文主要來介紹一下Java中的不可變對象,以及Java中String類的不可變性,那麼為什麼Java的String類是不可變對象?讓我們一起來分析一下。

作者:來源:codeceo|2015-03-19 15:04

答案三:String類不可變性的好處

String是所有語言中最常用的一個類。我們知道在Java中,String是不可變的、final的。Java在運行時也保存了一個字符串池(String pool),這使得String成為了一個特別的類。

String類不可變性的好處

1.只有當字符串是不可變的,字符串池才有可能實現。字符串池的實現可以在運行時節約很多heap空間,因為不同的字符串變量都指向池中的同一個字符串。但如果字符串是可變的,那麼String interning將不能實現(譯者註:String interning是指對不同的字符串僅僅只保存一個,即不會保存多個相同的字符串。),因為這樣的話,如果變量改變了它的值,那麼其它指向這個值的變量的值也會一起改變。

2.如果字符串是可變的,那麼會引起很嚴重的安全問題。譬如,資料庫的用戶名、密碼都是以字符串的形式傳入來獲得資料庫的連接,或者在socket編程中,主機名和埠都是以字符串的形式傳入。因為字符串是不可變的,所以它的值是不可改變的,否則黑客們可以鑽到空子,改變字符串指向的對象的值,造成安全漏洞。

3.因為字符串是不可變的,所以是多線程安全的,同一個字符串實例可以被多個線程共享。這樣便不用因為線程安全問題而使用同步。字符串自己便是線程安全的。

4.類加載器要用到字符串,不可變性提供了安全性,以便正確的類被加載。譬如你想加載java.sql.Connection類,而這個值被改成了myhacked.Connection,那麼會對你的資料庫造成不可知的破壞。

5.因為字符串是不可變的,所以在它創建的時候hashcode就被緩存了,不需要重新計算。這就使得字符串很適合作為Map中的鍵,字符串的處理速度要快過其它的鍵對象。這就是HashMap中的鍵往往都使用字符串。

以上就是我總結的Java字符串不可變性的好處,希望對你有所幫助。

【編輯推薦】

點讚 0

相關焦點

  • 為什麼Java字符串是不可變對象?(2)
    在Java中將String設計成不可變的是綜合考慮到各種因素的結果,想要理解這個問題,需要綜合內存,同步,數據結構以及安全等方面的考慮. 在下文中,我將為各種原因做一個小結。1.字符串常量池的需要字符串常量池(String pool, String intern pool, String保留池) 是Java堆內存中一個特殊的存儲區域, 當創建一個String對象時,假如此字符串值已經存在於常量池中,則不會創建一個新的對象,而是引用已經存在的對象。如下面的代碼所示,將會在堆內存中只創建一個實際String對象.
  • 萬字梳理,帶你拿下 Java 面試題!
    使用 new 關鍵字會在堆中創建一個對象,另外一個對象是 abc ,它會在常量池中創建,所以一共創建了兩個對象;如果 abc 在常量池中已經存在的話,那麼就會創建一個對象。8、String 為什麼是不可變的、jdk 源碼中的 String 如何定義的、為什麼這麼設計?
  • Java第七講:字符串
    字符串是由一對雙引號括起來的任意長度的字符序列。例如「你好」、「%&」、「 」,但是注意字符串不能包含斷行哦。字符串不是一個基本的類型(類似int和double),而是一個類。我們要創建一個字符串類的方法是:String greeting = 「你好」,它是String greeting = new String("你好")的縮寫形式。字符串在這方面是唯一的,字符串類的對象是唯一一種不需要new就可以創建的。我們可以用「+」號來連接字符串。
  • 「JAVA」萬字長篇詳述字節碼對象與反射機制完成動態編程
    類的字節碼類型:Class<java.util.ArrayList>;創建Class對象創建字節碼對象,有3種方式:(使用java.util.Date類做演示)1.> clazz3 = Class.forName("java.util.Date");在上述的代碼案例中使用了通配符「?」,通配符「?」表示「任何類」,通配符的使用使得Class對象的類型更加寬泛。
  • JSON對象和簡單練習
    >上一篇我們在SearchBookAJAXServlet.java中是用字符串拼接,這次我們這裡改成JSON。所以,使用JSON對象一句話就搞定了,比前面字符串拼接簡單多了。下面,來看看JSON的常見幾個操作。
  • 反射——Java高級開發必須懂得
    描述:在 main 函數中,有一個 String args[] 參數,這就表示在執行某 .class 文件時,可以對 main 函數傳字符串參數(例如:命令行中:java OfficeBetter Excel,傳給主函數的參數就是Excel,如果傳多個參數,參數用空格隔開),Office類中使用了兩個類(沒有提供這兩個類),並調用其相應的方法
  • Springmvc框架對json的支持 Java程式設計師必看
    這是我的jsp頁面,我們使用Jquery的方式對後端發送json字符串,這就需要引入jquery這個框架, 當我啟動項目是js死活都解析不出來jquery的路徑,經過好長一段時間的忙活終於找出來了問題所在,原來罪魁禍首就是springmvc中的DispatcherServlet,它把我的jquery
  • Java字符串地查找操作
    在一個字符串中查找字符或子串是經常使用的操作。String類提供了兩種查找字符串的方法,分別是indexOf()和lastIndexOf(),這兩種方法都返回待查找字符或子串在字符串的起始索引位置。調用語法如下:str.indexOf(s)其中,str是已創建的字符串對象,s待查找的字符串。案例1:創建一個字符串對象,使用indexOf()方法查找子串,如查找到子串輸出子串內容,否則輸出查找子串失敗信息。在PbaseUnit11項目unit包下創建StringSearchSample類。
  • Java之File類的構造方法
    ,也可以是以文件夾結尾,可以是相對路徑,也可以是絕對路徑,可以存在,也可以不存在,創建File對象,只是把字符串路徑封裝為File對象,不考慮路徑的真假情況代碼如下:public class Demo02File {
  • Java8 lambda表達式語法
    但是有一點這裡強調一下(Windows系統):目前我們工作的版本一般是java 6或者java 7,所以很多人安裝java8基本都是學習為主。這樣就在自己的機器上會存在多版本的JDK。而且大家一般是希望在命令行中執行java命令是基於老版本的jdk。但是在安裝完jdk8並且沒有設置path的情況下,你如果在命令行中輸入:java -version,屏幕上會顯示是jdk 8。
  • java之字符緩衝輸出流,BufferedWriter的簡單介紹
    各位小夥伴們,大家好在之前的文章中小編介紹了字節緩衝流的相關知識,這次小編要介紹的是字符緩衝輸出流,BufferedWriter,具體如下:java.io.BufferedWriter extends Writer
  • Java反射機制深入詳解
    1 Person p1 = new Person(); 2 //下面的這三種方式都可以得到字節碼 3 CLass c1 = Date.class(); 4 p1.getClass(); 5 //若存在則加載,否則新建,往往使用第三種,類的名字在寫源程序時不需要知道,到運行時再傳遞過來 6 Class.forName("java.lang.String");CLass.forName
  • 2020年Java基礎高頻面試題匯總
    String是只讀字符串,它並不是基本數據類型,而是一個對象。從底層源碼來看是一個nal類型的字符數組,所引用的字符串不能被改變,一經定義,無法再增刪改。每次對String的操作都會生成新的String對象。
  • JavaScript基礎-內置對象
    Date 對象和 Math 對象不一樣,Date是一個構造函數,所以使用時需要實例化後才能使用其中具體方法和屬性。賦值給我們聲明的字符變量str = temp;// 3. 銷毀臨時變量temp = null;字符串的不可變 指的是裡面的值不可變,雖然看上去可以改變內容,但其實是地址變了,內存中新開闢了一個內存空間。
  • Java中可變參數的使用方式
    在Java的參數定義中,有一種比較特殊的定義方式,就是可變參數。可能有的朋友對這個名稱有點陌生,但是看到代碼可能就會說,「就是他啊」。那這個可變參數是什麼呢,就是類似下面這個方法籤名中的參數的定義方式了。
  • 給JAVA程式設計師的正則表達式一課
    注意還有一個逆序環視,java中不支持,我們不介紹。貪婪和懶惰正則表達式中的的量詞默認貪婪的,匹配時候會儘可能多的匹配,這樣才能減少遞歸回溯搜索的次數,因而效率最高。例如,對於正則表達式a.+c,希望它表示文本應為'a',後跟一個或多個非空格字符。
  • (提高Java代碼質量)|25個優化Java代碼的小技巧
    不要把集合對象傳給自己將集合作為參數傳遞給集合自己的方法要麼是一個錯誤,要麼是無意義的代碼。反例:正例:5.字符串拼接使用 StringBuilder一般的字符串拼接在編譯期 java 會進行優化,但是在循環中字符串拼接,java 編譯期無法做到優化,所以需要使用 StringBuilder 進行替換。
  • 大神詳解,這麼詳細的Java設計模式不收藏可惜了
    為什麼再看一遍設計模式,主要有幾個原因:***,很多優秀的源碼基本都使用了設計模式,明確設計模式能夠更好的看源碼。第二,很多中間件設計理念也是基於設計模式的,還有其他的語言,都有自己的設計優秀實踐。對於我來說,設計模式始於java,不止於java。第三,有了這種規範,可以更好的和他人溝通,言簡意賅。
  • 開發崗位這麼多,為什麼選Java?你學Java了嗎-開課吧
    軟體開發可以使用的語法是非常多,但是為什麼Java被廣泛的使用呢?其他程式語言與Java相比,Java語法相對簡單,並且是很多計算機語言的基礎。提到C++語言,很多人發現在使用過程中最容易出現的錯誤就是內存管理,而java有自動垃圾回收器,不用擔心內存。
  • java基礎教程:Collection集合,Collection 常用API
    集合:集合是java中提供的一種容器,可以用來存儲多個數據。集合和數組既然都是容器,它們有什麼區別呢?數組的長度是固定的。集合的長度是可變的。數組中存儲的是同一類型的元素,可以存儲任意類型數據。集合存儲的都是引用數據類型。如果想存儲基本類型數據需要存儲對應的包裝類型。