簡體   English   中英

Java String文字池和字符串對象

[英]Java String literal pool and string object

我知道JVM維護一個字符串文字池來提高性能並維護JVM內存,並了解到字符串文字是在字符串池中維護的。 但我想澄清與堆上創建的字符串池和字符串對象相關的內容。

如果我的解釋錯誤,請糾正我。

String s = "abc";

如果執行上面的行,如果池中不存在“abc”字符串文字,則將其添加到字符串池中。 並且在堆上創建字符串對象,引用s將指向池中的文字。

問題:

  1. 這個代碼每次執行時都會在堆上創建字符串對象嗎?
  2. 字符串文字池是僅維護字符串文字還是維護字符串對象?
  3. JVM何時決定是否需要將字符串文字添加到字符串池中? 它是在編譯時還是運行時決定的?

如果它指向池中的字符串文字,我不確定在哪里創建字符串對象。

謝謝。

沒有“文字池”。 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; 它不一定來自文字。

所以關於你的問題:

  1. 不,在加載類時會分配一個String對象。
  2. 它不維護任何文字,而是維護實體的String對象。 通常,那些來自文字,但實際上它可以是任何編譯時常量表達式( String constant = "abc" + "def"將在運行時產生一個String對象“abcdef”)。
  3. 它們被編譯到類文件中。 所以它們是在編譯時決定的,但顯然對象本身是在運行時創建的。

這個代碼每次執行時都會在堆上創建字符串對象嗎?

不。 一旦在文字池中創建。 同樣一次又一次地提到。

字符串文字池是僅維護字符串文字還是維護字符串對象?

所有都只是對象,但通過賦值創建的對象放在池中,而通過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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM