為什麼說String是不可變的

2021-08-02 07:24:36 字數 1119 閱讀 5483

簡單的例子:

string s1= 「abc」;

string s1=s1;

s1= 「def」;

此時s1變化了嗎?變了!s1的位址從指向 「abc」變成指向 「def」;

重要的不在這裡,記憶體上的「abc」本身並沒有被改變!指向 「abc」的s2也沒有被改變

兩個final ,乙個在string的類修飾符,乙個是string內部儲存資料的陣列value的變數修飾符

public final class string

private final char value;

string類是用final關鍵字修飾,這說明string不可繼承。

實質上用以儲存內容的屬性value 的定義 final char,final修飾的字段建立以後就不可改變,這裡指的是引用的位址將不可以再變

但是現在來看問題並沒有解決,string本身依舊是可變的,雖然引用位址不再能變化,但是陣列本身的內容還是可以變化的

也就是說array變數只是stack上的乙個引用,資料的本體結構在heap堆。string類裡的value用final修飾,只是說stack裡的這個叫value的引用位址不可變。沒有說堆裡array本身資料不可變。看這個這個例子

所以看來,string 不可變並不是因為兩個final

簡單來說這是作為字面量的個人修養

回看第一部分,s2並沒有被改變,這正是作為字面量的意義的體現!

沒有這個特性,任何語言的基礎都將不復存在,因為你無法保證你存的內容是不會被其他執行緒或者其他的不想管的操作所影響。

另外,考慮到字串池本身存在的意義正式讓大量存在大量使用的字串不會被重複的建立銷毀,因為在系統級別看來,這種對效能的損耗是不可接受的

string的不可變還是要結合堆來看,他的不可變是字串池裡的物件不可變,而不是我們建立的string不可變

eg:補充一下

還有一些問題是相關的

比如string s1=new string(「abc」);這個過程建立了幾個物件?

之前沒有建立過,則建立兩個物件 乙個在堆 乙個在permgen常量池

在java中,說String是不可變的,可是為什麼

假設string s new string wo string s1 new string de s s s1 system.out.println s 結果為wode?首先在棧中有個 s 變數指向堆中的 wo 物件.棧中 s1 變數指向堆中的 de 物件 當執行到 s s s1 系統重新在堆中ne...

String 為什麼要設計成不可變的

string不可變 string值儲存在常量池中。乙個已有字串 abcd 如果改變值成 abcedl 不是在原記憶體位址上修改資料,而是在常量池中查詢或生成這個新值,再把引用指向新值的位址,如圖 string 類本身是final的,不可以被繼承 string類內部通過private final ch...

C string 是不可變的,指什麼不可變

string 表示文字,即一系列 unicode 字元。字串是 unicode 字元的有序集合,用於表示文字。string 物件是 system.char 物件的有序集合,用於表示字串。string 物件的值是該有序集合的內容,並且該值是不可變的。string 物件稱為不可變的 唯讀 因為一旦建立了...