2013-01-18 23 views
4

可能重複:
When should we use intern method of String?
what is string interning?請解釋實習生()方法的功能

請解釋下面的代碼的內部工作:

System.out.println(new String("ABC").intern()==new String("ABC").intern()); 

在上面的代碼打印「true」。但是根據java規則,對於new運算符,它總是創建一個新對象。 object.intern()方法也會在字符串池中創建一個對象。所以我的問題是,在上面的代碼中創建了多少個對象。

據我所知,會創建3個新對象。一個進入字符串池,兩個匿名對象將由新運算符創建。但我不確定。

如果我錯了,請解釋。

+0

http://en.wikipedia.org/wiki/String_interning – Jayan

+0

也有一些相關的信息:http://stackoverflow.com/questions/7065337/intern-behaving -differently-in-java-6-and-java-7 – Jayan

+0

一個簡短的例子是'System.out.println(「ABC」== new String(「ABC」)。intern());' –

回答

0

當您調用intern()方法時,jvm將檢查給定的字符串是否存在於字符串池中。如果它在那裏,它會返回一個引用,否則它會在池中創建一個新的字符串並返回對該字符串的引用。 你的情況:System.out.println(new String("ABC").intern()==new String("ABC").intern());

new String("ABC").intern()將創建一個字符串「ABC」在pool.When你叫new String("ABC").intern()秒時,JVM將返回參考預先創建string.That是比較當你得到true的原因兩個(btn都指向相同的參考)。

+0

我認爲他的問題是「創建了多少個對象?」不是爲什麼它返回true –

+0

你是對的。將創建三個對象(在字符串中,只有在池沒有ABC字符串時纔會創建新字符串) – Renjith

0

我相信你是對的,因爲new操作創建一個新的對象,因此有2個匿名對象和intern()創建的字符串池一個新的字符串,只有當它是不是已經返回它的參考

1

假設沒有聰明在優化器中,創建兩個對象。 (一個足夠聰明的優化器可以優化這只是一個無條件true,在這種情況下不創建對象。)

TL;博士版本:你是差不多吧你的3回答,除了字符串去不會生成字符串池作爲此語句的一部分;它已經創建。

首先,讓我們看看"ABC"。它在運行時中表示爲String對象,但它存在於pergen中,並且在JVM的整個生命週期中都創建了一次。如果這是使用該字符串文字的第一個類,則它是在類加載時創建的(請參閱JLS 12.5,其中聲明該字符串是在加載類時創建的,除非它以前存在)。

所以,第一個new String("ABC")創建一個String,它只是copies the reference(但不創建新的對象)的字符陣列和散列從字符串表示該"ABC"字面(再次,沒有作爲的一部分創建這條線)。 .intern()方法然後查看是否相同的字符串已經在permgen中。它是(它只是表示開頭的字符串),所以這就是函數返回的結果。那麼,new String("ABC").intern() == "ABC"。見JLS 3.10.5,特別是:

此外,一個字符串文字總是指String類的相同實例。這是因爲字符串文字 - 或者更一般地說是常量表達式(§15.28)值的字符串 - 被「實施」,以便使用方法String.intern共享唯一實例。

第二次出現new String("ABC").intern()時也發生了同樣的情況。而且,由於intern()方法返回與"ABC"文字相同的對象,它們表示相同的值。

打破下來了一點:

String a = new String("ABC"); // a != "ABC" 
String aInterned = a.intern(); // aInterned == "ABC" 

String b = new String("ABC"); // b != "ABC" 
String bInterned = b.intern(); // bInterned == "ABC" 

System.out.println(new String("ABC").intern()==new String("ABC").intern()); 
              // ... is equivalent to... 
System.out.println(aInterned == bInterned); // ...which is equivalent to... 
System.out.println("ABC" == "ABC");   // ...which is always true.