日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

String类为什么被设计为不可变的?

發布時間:2025/3/20 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 String类为什么被设计为不可变的? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

點擊上方?好好學java?,選擇?星標?公眾號

重磅資訊、干貨,第一時間送達 今日推薦:都說了多少遍,不要再學 JSP 了!個人原創100W+訪問量博客:點擊前往,查看更多

從哪看出來String類是不可變的?

public?final?class?Stringimplements?java.io.Serializable,?Comparable<String>,?CharSequence?{/**?The?value?is?used?for?character?storage.?*/private?final?char?value[]; }

String類的值是保存在value數組中的,并且是被private final修飾的

  • private修飾,表明外部的類是訪問不到value的,同時子類也訪問不到,當然String類不可能有子類,因為類被final修飾了

  • final修飾,表明value的引用是不會被改變的,而value只會在String的構造函數中被初始化,而且并沒有其他方法可以修改value數組中的值,保證了value的引用和值都不會發生變化

  • final關鍵字的作用有如下幾種

  • final修飾類時,表明這個類不能被繼承

  • final修飾方法,表明方法不能被重寫

  • final修飾變量,如果是基本數據類型的變量,則其數值一旦在初始化之后便不能改變;如果是對象類型的變量,只能保證它的引用不變,但對象的內容是可以改變的

  • 在Java中數組也是對象,數組即使被final修飾,內容還是可以改變的

    所以我們說String類是不可變的。

    附上我歷時三個月總結的?Java 面試 + Java 后端技術學習指南,筆者這幾年及春招的總結,github 1.1k star,拿去不謝!

    下載方式

    1.?首先掃描下方二維碼

    2.?后臺回復「Java面試」即可獲取

    而很多方法,如substring并不是在原來的String類上進行操作,而是生成了新的String類

    public?String?substring(int?beginIndex)?{if?(beginIndex?<?0)?{throw?new?StringIndexOutOfBoundsException(beginIndex);}int?subLen?=?value.length?-?beginIndex;if?(subLen?<?0)?{throw?new?StringIndexOutOfBoundsException(subLen);}return?(beginIndex?==?0)???this?:?new?String(value,?beginIndex,?subLen); }

    為什么String被設置為不可變的?

    字符串常量池

    字符串常量池可以節省大量的內存空間。如果String類可變就不可能有字符串常量池

    字符串常量池放在哪?

    jdk1.7之前的不討論,從jdk1.7開始,字符串常量池就開始放在堆中,然后本文的所有內容都是基于jdk1.8的

    下面這個代碼還是經常被問到的

    String?str1?=?"abc"; String?str2?=?"abc"; String?str3?=?new?String("abc"); String?str4?=?new?String("abc"); //?true System.out.println(str1?==?str2); //?false System.out.println(str1?==?str3); //?false System.out.println(str3?==?str4);

    內存中的結構如下其中常量池中存的是引用

    解釋一下上面代碼的輸出,Java中有2種創建字符串對象的方式

    String?str1?=?"abc"; String?str2?=?"abc"; //?true System.out.println(str1?==?str2);

    采用字面值的方式創建一個字符串時,JVM首先會去字符串池中查找是否存在"abc"這個對象的引用

    如果不存在,則在堆中創建"abc"這個對象,并將其引用添加到字符串常量池(實際上是將引用放到哈希表中),隨后將引用賦給str1

    如果存在,則不創建任何對象,直接將池中"abc"對象的引用返回,賦給str2。因為str1、str2指向同一個對象,所以結果為true。

    String?str3?=?new?String("abc"); String?str4?=?new?String("abc"); //?false System.out.println(str3?==?str4);

    采用new關鍵字新建一個字符串對象時,JVM首先在字符串池中查找有沒有"abc"這個字符串對象的引用

    如果沒有,則先在堆中創建一個"abc"字符串對象,并將引用添加到字符串常量池,隨后將引用賦給str3

    如果有,則不往池中放"abc"對象的引用,直接在堆中創建一個"abc"字符串對象,然后將引用賦給str4。這樣,str4就指向了堆中創建的這個"abc"字符串對象;

    因為str3和str4指向的是不同的字符串對象,結果為false。

    緩存HashCode

    String類在被創建的時候,hashcode就被緩存到hash成員變量中,因為String類是不可變的,所以hashcode是不會改變的。這樣每次想使用hashcode的時候直接取就行了,而不用重新計算,提高了效率

    public?final?class?Stringimplements?java.io.Serializable,?Comparable<String>,?CharSequence?{/**?Cache?the?hash?code?for?the?string?*/private?int?hash;?//?Default?to?0}

    可以用作HashMap的key

    由于String類不可變的特性,所以經常被用作HashMap的key,如果String類是可變的,內容改變,hashCode也會改變,當根據這個key從HashMap中取的時候有可能取不到value,或者取到錯的value

    線程安全

    不可變對象天生就是線程安全的,這樣可以避免在多線程環境下對String做同步操作

    最后,再附上我歷時三個月總結的?Java 面試 + Java 后端技術學習指南,筆者這幾年及春招的總結,github 1.1k star,拿去不謝!

    下載方式

    1.?首先掃描下方二維碼

    2.?后臺回復「Java面試」即可獲取

    《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

    總結

    以上是生活随笔為你收集整理的String类为什么被设计为不可变的?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。