你真的了解String的建立嗎?

2021-10-08 15:55:05 字數 1847 閱讀 6605

在文章的開始之前,有乙個問題需要思考。

string s =

"mryan"

;

string s =

newstring

("mryan"

);

以上是string的兩種賦值方式,它們有什麼區別嗎?它們在記憶體中有幾個例項?儲存在哪個區域裡?例項儲存在**?字面量儲存在**?想要回答這些問題,需要對jvm有一定的了解

其中在jdk1.7以後包括常量池,執行時常量池,字串常量池都由方法區移動到了堆記憶體中。

有了以上知識點,我們可以繼續說回string了

編寫一段**如下:

package com.mryan.csdn.string;

class

test

}

宣告了乙個字面量為「mryan」的字串,因為由於string的不可變性(被final修飾)所以字串"mryan"作為字面量儲存在class檔案常量池中。

類載入之後class檔案裡常量池裡大部分資料會被載入到執行時常量池,但是string型別的資料的引用會被同時存在字串常量池中,例項建立在堆中。

而其實這只是test類被類載入的時候,並未有啟動程式執行緒,此時「mryan」的引用已經存放在字串常量池中,例項存放在堆中。

等主線程開始建立s1變數時,jvm就會到字串常量池裡找,看有沒有能equals(「mryan」)的string。如果找到了,就在虛擬機器棧中當前棧幀的區域性變數表裡建立s1變數,然後把字串常量池裡對mryan物件的引用複製給s1變數。找不到的話,才會在heap堆重新建立乙個物件,然後把引用駐留到字串常量區。然後再把引用複製棧幀的區域性變數表。

畫個簡圖:

當定義了多個值為"mryan"的string,情況是什麼樣的呢?

package com.mryan.csdn.string;

class

test

}

輸出:

但如果是用new關鍵字來建立字串,情況就不一樣了

package com.mryan.csdn.string;

class

test

}

輸出:

這時候,s1和s2還是和之前一樣。但s3不同因為new關鍵字會在heap堆申請一塊全新的記憶體,來建立新物件。雖然字面還是"mryan",但是完全不同的物件,有不同的記憶體位址。

畫個簡圖:

到這裡文章開篇的問題你應該都能答出來吧。

你真的了解JAVA裡的String嗎?

1.string str1 abc system.out.println str1 abc 步驟 1 棧中開闢一塊空間存放引用str1,2 string池中開闢一塊空間,存放string常量 abc 3 引用str1指向池中string常量 abc 4 str1所指代的位址即常量 abc 所在位址,...

你真的了解Java嗎?

三目運算子規則 如果第二個和第三個運算元具有相同的型別,那麼它就是條件表示式的類 型。換句話說,你可以通過繞過混合型別的計算來避免 煩。如果乙個運算元的型別是 t,t 表示 byte short 或 char,而另乙個運算元是乙個 int 型別的常量表示式,它的值是可以用型別 t 表示的,那麼條件表...

你真的了解restful api嗎?

在以前,乙個 的完成總是 all in one 頁面,資料,渲染全部在服務端完成,這樣做的最大的弊端是後期維護,擴充套件極其痛苦,開發人員必須同時具備前後端知識。於是慢慢的後來興起了前後端分離的思想 後端負責資料編造,而前端則負責資料渲染,前端靜態頁面呼叫指定api獲取到有固定格式的資料,再將資料展...