[英]Java String literal pool and string object
我知道JVM維護一個字符串文字池來提高性能並維護JVM內存,並了解到字符串文字是在字符串池中維護的。 但我想澄清與堆上創建的字符串池和字符串對象相關的內容。
如果我的解釋錯誤,請糾正我。
String s = "abc";
如果執行上面的行,如果池中不存在“abc”字符串文字,則將其添加到字符串池中。 並且在堆上創建字符串對象,引用s
將指向池中的文字。
問題:
如果它指向池中的字符串文字,我不確定在哪里創建字符串對象。
謝謝。
沒有“文字池”。 Interned Strings只是普通的堆對象。 它們最終可能會進入PermGen,但即便如此,它們最終也可能被垃圾收集。
類文件有一個常量池,它包含類中使用的字符串文字。 加載類時,會根據該數據創建String對象,這可能與String #intern的內容非常相似。
這個代碼每次執行時都會在堆上創建字符串對象嗎?
不會。將有一個正在重用的String對象。 它已在加載類時創建。
字符串文字池是僅維護字符串文字還是維護字符串對象?
你也可以實習弦樂。 我認為他們的待遇大致相同。
JVM何時決定是否需要將字符串文字添加到字符串池中? 它是在編譯時還是運行時決定的?
文字總是“匯集”。 其他字符串需要在其上調用“實習生”。 所以在某種程度上,決定是在編譯時做出的。
引用String.intern()的文檔( 強調我的 )
所有文字字符串和字符串值常量表達式都是實體。 字符串文字在Java語言規范的§3.10.5中定義
最初為空的字符串池由String類私有維護。
調用實習方法時,如果池已經包含等於此字符串對象的字符串(由equals(Object)方法確定),則返回池中的字符串。 否則,將此String對象添加到池中,並返回對此String對象的引用。
這個代碼每次執行時都會在堆上創建字符串對象嗎?
僅為每個唯一的實習字符串創建一個對象。 所有引用都共享此不可變對象。
字符串文字池是僅維護字符串文字還是維護字符串對象?
沒有'文字對象'。 轉換后的文字字符串表達式存儲為常規String
對象。此外,池包含所有實體字符串對象。 隱式(通過使用字符串文字表達式)和顯式(通過在String
對象上調用.intern()
)。
JVM何時決定是否需要將字符串文字添加到字符串池中? 它是在編譯時還是運行時決定的?
我不確定。
我認為你缺少一些基本的東西:實習字符串池只包含String對象。 文字不是某種特殊的對象; 在運行時,它們只是另一個String對象。
另外,你可以使用String.intern()
實習你想要的任何String; 它不一定來自文字。
所以關於你的問題:
String constant = "abc" + "def"
將在運行時產生一個String對象“abcdef”)。 這個代碼每次執行時都會在堆上創建字符串對象嗎?
不。 一旦在文字池中創建。 同樣一次又一次地提到。
字符串文字池是僅維護字符串文字還是維護字符串對象?
所有都只是對象,但通過賦值創建的對象放在池中,而通過new
運算符創建的對象放在堆上。
JVM何時決定是否需要將字符串文字添加到字符串池中? 它是在編譯時還是運行時決定的?
每當JVM遇到類似的表達式時
String str="Hello"; (string literal) or
String str="Hel" + "lo"; (string constant expression).
並且結果字符串(在本例中為str
)不是池,然后在所有這些情況下,它在池中添加新字符串。 這個過程在運行時發生。
看看這個鏈接。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.