Java的StringPool是存放在方法区中,是所有类共享的吗?
巴扎黑
巴扎黑 2017-04-17 11:16:07
0
4
937

Java虚拟机中,每个类都有一个常量池,StringPool存在常量池中,对于A.StringA.intern()==B.StringB.intern()应该返回False~~可是我打出来的是True,Why?

巴扎黑
巴扎黑

全部回覆(4)
阿神

每個類別中的常數池:

java的每一個類別都有一個常數池,這個常數池定義在.class檔案中有描述,包括整形、浮點型、字串、類別名稱、屬性名稱、方法宣告等。當jvm裝載.class檔案時,會裝載這些常數池信息,並按照JMM(java存儲模型)的定義,在方法區(即常說的PermGen Space[永久代])中開闢一塊內存空間,用以存儲這些常量。

要注意的是:

java同時會在方法區維持一個string pool,在裝載常數池的字串型常數時,會先將這些字串常數儲存到string pool中,然後傳回其引用給每個類別的常數池。

至於String.intern()方法,引用其JavaDoc:

A pool of strings, initially empty, is maintained privately by the class String.

When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the {@link #equals(Object)} method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.

It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true.

加粗標明的行也說明了java在方法區中會維持string pool。至於為什麼

A.StringA.intern()==B.StringB.intern()會回傳true

相信你看了javaDoc會明白。

PS:不光String類別有JVM原生支援的常數池,Boolean、Byte、Character、Short、Integer、Long這六種原始類型包裝類,也實作了程式碼層級的常數池,具體可參考JDK源碼。
PPS:可供參考常數池

阿神

Java Doc:

"When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. the pool and a reference to this String object is returned. "

是說, 在呼叫str.intern()時, 首先去pool中找是否有equals(str)==true的字串. 找到後返回已存在於pool裡的字串, 否則把str加入pool中.

所以在pool裡, 相等的字串 只會有一份.

刘奇

可能我問題有點問題~,「運行時常數池是方法去的一部分,Class檔案中除了有類別的版本、欄位、方法、介面等描述資訊外,還有一項資訊就是常數池,用於存放編譯器產生的各種字面量和符號引用,這部分內容在類別載入後存放在方法區的運行時常數池中。時常量池的一個引用

伊谢尔伦

如果字串StringA和StringB有著相同的內容,那麼上面的語句StringA.intern()==StringB.intern()為true,因為他們指向的為同一個物件。

呼叫intern後,首先檢查字串常數池中是否有該物件的引用,如果存在,則將這個引用傳回給變量,否則將引用加入並傳回給變數。

具體可以參考Java中的字串常數池

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板