簡體   English   中英

String.intern()的返回解釋

[英]The return of String.intern() explained

考慮:

String s1 = new StringBuilder("Cattie").append(" & Doggie").toString();
System.out.println(s1.intern() == s1); // true why?
System.out.println(s1 == "Cattie & Doggie"); // true another why?

String s2 = new StringBuilder("ja").append("va").toString();
System.out.println(s2.intern() == s2); // false

String s3 = new String("Cattie & Doggie");
System.out.println(s3.intern() == s3); // false
System.out.println(s3 == "Cattie & Doggie"); // false

我很困惑為什么它們由於String.intern()返回值而產生不同的結果 ,它說:

調用實習方法時,如果池已經包含等於此字符串對象的字符串(由equals(Object)方法確定),則返回池中的字符串。 否則,將此String對象添加到池中,並返回對此String對象的引用。

特別是經過這兩項測試:

assertFalse("new String() should create a new instance", new String("jav") == "jav");
assertFalse("new StringBuilder() should create a new instance",
    new StringBuilder("jav").toString() == "jav");

我曾經讀過一篇文章,談論在其他事情之前被拘留的一些special strings ,但現在它真的很模糊。

如果pre-interned存在一些字符串,是否有辦法獲得它們的列表? 我只是好奇他們會是什么。


更新

感謝@Eran和@Slaw的幫助,我終於可以解釋輸出中剛剛發生了什么

true
true
false
false
false
  1. 由於"Cattie & Doggie"不存在"Cattie & Doggie" ,s1.intern()會將當前對象引用放入池中並返回自身,因此s1.intern() == s1 ;
  2. "Cattie & Doggie"現在已經在游泳池中,所以字符串文字"Cattie & Doggie"將只使用池中的引用,實際上是s1 ,所以我們再次true ;
  3. new StringBuilder().toString()將創建一個新實例,而"java"已經在池中,然后在調用s2.intern()時將返回池中的引用,所以s2.intern() != s2和我們有false
  4. new String()也將返回一個新實例,但是當我們嘗試s3.intern() ,它將返回池中先前存儲的引用,該引用實際上是s1所以s3.intern() != s3並且我們有false ;
  5. 正如#2已經討論過的那樣,字符串文字"Cattie & Doggie"將返回已經存儲在池中的引用(實際上是s1 ),所以s3 != "Cattie & Doggie" ,我們又false了。

感謝@Sunny提供了獲取所有interned字符串的技巧。

僅當String池在該調用之前不包含值為“java”的Strings2.intern()才會返回s2引用的實例。 JDK類在執行代碼之前實際執行一些String “java”必須是其中之一。 因此, s2.intern()返回先前實例化的實例而不是s2

另一方面,JDK類沒有實現任何其值等於“Cattie&Doggie”的String ,因此s1.intern()返回s1

我不知道任何預先實習的字符串列表。 這樣的列表很可能被認為是一個實現細節,它可能因不同的JDK實現和JDK版本而有所不同,不應該依賴。

當在String對象上調用intern()方法時,它會查找池中此String對象包含的字符串,如果在那里找到該字符串,則返回池中的字符串。 否則,將此String對象添加到池中,並返回對此String對象的引用。

所以java字符串必須已經在池中。 因此它是虛假的。

您可以在池中打印所有字符串

如何打印整個String池?

以下是使用openjdk獲取所有字符串的示例

字符串文字(像“字符串”這樣硬編碼的字符串文字)已由編譯器為您實現。 但是那些以編程方式獲取的字符串不會,並且只有在使用.intern()方法時才會被實現。

通常你不會手動實習字符串,除非你知道你將在內存中存儲大量重復字符串,這樣你就可以節省大量內存。

這里解釋了: Java String interning是什么?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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