亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Java的String不可變性

atinosun / 995人閱讀

摘要:但是通過構造函數(shù)的并不是。通過構造函數(shù)創(chuàng)建的變量在機制上與其他對象一致,都是在上創(chuàng)建新的對象,然后把引用賦給變量。此外,的方法和等方法實現(xiàn)均是調(diào)用了構造函數(shù)創(chuàng)建了新的對象,所以他們返回的也都是存在于上的新對象。

String經(jīng)常在一個語言中或多或少都有些特殊地位。在Java亦不例外。今天先來討論,String是不可變的。

String是引用類型,String變量儲存一個地址,地址指向內(nèi)存堆中的String對象。當我們說變量不可變,有兩種不可變性:

變量儲存的地址不可變;

地址指向的對象內(nèi)容不可變。

String的不可變指的是哪一種?下面用例子來看。

通常有人在疑問String不可變時,會舉這樣的例子:我們平時不都像下面這樣在“修改”String字符串嗎:

String s = "hello,world";
s = "Hello,coder";
System.out.println(s);    //Hello,coder

我認為這只是一個語義上的誤導。賦值操作符=通常作用于基本數(shù)據(jù)類型時,確是修改變量的值。所以在這里讓人誤以為也是修改了變量的內(nèi)容。但是對于引用類型String,s="Hello,coder"的實際作用是將變量s指向另一個內(nèi)容為Hello,coder的新的對象。

所以,對于String不可變性的結論顯而易見了:String變量指向的地址是可變的,他的不可變性當然說的是第二種——地址指向的對象內(nèi)容不可變。

縱覽String的方法,String類確實沒有提供能從String外部修改對象的方法。我們熟悉的replace,substring等等方法都要返回一個String,其實都是在返回一個新的對象,而沒有修改原有的對象。

為什么要設計成對象內(nèi)容不可變?

String常量池

一個說法是便于實現(xiàn)String常量池。String存在于常量池中,當新創(chuàng)建一個字符串變量,如果字符串在內(nèi)存中已經(jīng)存在,那么就會把這個已經(jīng)存在于常量池對象的地址賦給變量。這樣可節(jié)省內(nèi)存開銷。

但這不完全對。

只有兩種情況下創(chuàng)建的String變量,他們才會指向常量池中的同一對象:

String是字面直接量賦值創(chuàng)建。字面直接量是編譯期常量,變量會指向常量池中的對象。所有字面量賦值創(chuàng)建的String變量都會指向常量池中的對象。

通過String類的intern()方法得到String變量也是指向常量池中的對象。

但是通過構造函數(shù)new String()的并不是。通過構造函數(shù)創(chuàng)建的String變量在機制上與其他對象一致,都是在heap上創(chuàng)建新的對象,然后把引用賦給變量。

簡單例子驗證。

String a = "hello,world";
String b = "hello,world";
boolean c = (a == b);                  //true

String d = new String("hello,world");
String e = new String("hello,world");;
boolean f = (d == e);                  //false

String g = d.intern();
boolean h = (a == g);                 //true

此外,String的方法substring,relpacesplit等方法實現(xiàn)均是調(diào)用了構造函數(shù)創(chuàng)建了新的對象,所以他們返回的String也都是存在于heap上的新對象。

綜上來看似乎節(jié)省不了多少內(nèi)存,畢竟程序中編譯常量是少數(shù),大多數(shù)String都是在運行時產(chǎn)生。

線程安全

這一點顯而易見,對象內(nèi)容都不可變了,自然不會有線程安全問題。

代碼安全

String經(jīng)常被用來存儲server connection, database connection或者file path等等。如果String可變,一旦代碼某處改動了字符串,會對系統(tǒng)有安全和穩(wěn)定性威脅。發(fā)生在其他普通字符串,則是不可預料的bug。尤其是代碼復雜度很高的時候,一個字符串對象被多個變量引用,直接修改對象內(nèi)容,引起所有引用該對象的變量都發(fā)生變化,容易引起bug。

當然這一點主要是降低程序員的錯誤和bug的可能。

其實,話說回來,在JAVA里,String不可變也并非特殊,所有包裝類Interger,Boolean等都是不可變類。

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://www.ezyhdfw.cn/yun/77028.html

相關文章

  • 記一次愚蠢經(jīng)歷--String不可變性

    摘要:文本已收錄至我的倉庫,歡迎記錄一次在寫代碼時愚蠢的操作,本文涉及到的知識點不可變性一交代背景我這邊有一個系統(tǒng),提供一個接口去發(fā)送短信。 前言 只有光頭才能變強。文本已收錄至我的GitHub倉庫,歡迎Star:https://github.com/ZhongFuCheng3y/3y 記錄一次在寫代碼時愚蠢的操作,本文涉及到的知識點:String不可變性 一、交代背景 我這邊有一個系統(tǒng),...

    woshicixide 評論0 收藏0
  • String 不可變性

    摘要:的不變性,如下圖所示,當你改變了的之后指向了一個新的對象原對象不做改變。但其引用的數(shù)組是可變的。所以的不可變性的關鍵并不是的作用。同時編寫者為了避免因為的不可變性導致占用大量空間,為此設計了字符串常量池 在貓眼的面試中被面試官問到為什么String的字符串是不變的。當時我的回答是因為String類是用final關鍵字修飾的,當被問到為什么用 final修飾就是不可變的時候我發(fā)現(xiàn)自己說的...

    sydMobile 評論0 收藏0
  • 第3章:抽象數(shù)據(jù)類型(ADT)和面向對象編程(OOP) 3.1數(shù)據(jù)類型和類型檢查

    摘要:所有變量的類型在編譯時已知在程序運行之前,因此編譯器也可以推導出所有表達式的類型。像變量的類型一樣,這些聲明是重要的文檔,對代碼讀者很有用,并由編譯器進行靜態(tài)檢查。對象類型的值對象類型的值是由其類型標記的圓。 大綱 1.編程語言中的數(shù)據(jù)類型2.靜態(tài)與動態(tài)數(shù)據(jù)類型3.類型檢查4.易變性和不變性5.快照圖6.復雜的數(shù)據(jù)類型:數(shù)組和集合7.有用的不可變類型8.空引用9.總結 編程語言中的數(shù)據(jù)...

    zhangqh 評論0 收藏0
  • Java String類筆記

    摘要:這兩個操作符都是編譯器默認引入了類,最后都調(diào)用方法返回對象,臨時對象被回收,因此效率極為低下 Java String類筆記 聲明 文章均為本人技術筆記,轉載請注明出處https://segmentfault.com/u/yzwall String的不可變性 String的不可變性 // String declaration public final class String ...

    Vicky 評論0 收藏0
  • StringString類型為什么不可

    摘要:性能當字符串是不可變時,字符串常量池才有意義。字符串常量池的出現(xiàn),可以減少創(chuàng)建相同字面量的字符串,讓不同的引用指向池中同一個字符串,為運行時節(jié)約很多的堆內(nèi)存。 在學習Java的過程中,我們會被告知 String 被設計成不可變的類型。為什么 String 會被 Java 開發(fā)者有如此特殊的對待?他們的設計意圖和設計理念到底是什么?因此,我?guī)е韵氯齻€問題,對 String 進行剖析: ...

    zhiwei 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<