2009-12-13 19 views
5
public class A { 

    static String s1 = "I am A"; 

    public static void main(String[] args) { 
     String s2 = "I am A"; 
     System.out.println(s1 == s2); 
    } 
} 

上面的程序輸出 「真」。兩者都是兩個不同的標識符/對象輸出是如何「真」的?基本的Java問題:字符串平等

我的理解是,JVM會爲每個對象不同的參考,如果輸出是那麼如何正確的?

回答

20

的Java管理一個String文字池。它可以重用這些文字。因此這兩個對象實際上是相同的String對象,並且==返回true。

我相信這就是所謂的string interning

+1

有關字符串池的信息,請查看維基百科:http://en.wikipedia.org/wiki/String_interning(+1同一想法) – 2009-12-13 10:55:17

+1

是的,字符串文字會根據實習方法API - http ://java.sun.com/javase/6/docs/api/java/lang/String.html – Ash 2009-12-13 10:55:39

+1

這不僅僅是文字,也是編譯時常量。 – 2009-12-13 10:59:25

1

你是不是比較字符串的內容。你只是比較對象的引用。你應該使用equal方法(它是String類的成員)。無論是或者你可以使用compareTo方法(也在同一個String類下)來檢查返回值是否爲零。

請注意上面的文字更強烈建議對問題的原單狀態,它出現在OP不知道實際過程會在幕後的。

其他的人暗示internalling是正確的。爲了回答這個問題,我沒有足夠的時間去看Java Puzzlers書籍。我確實懷疑在編譯時設置了相同的引用,但我不知道如何找到這個引用。

+0

如果我比較的內容那麼答案肯定是‘真’,但這裏都是兩個不同的變量,贏得't jvm創建兩個不同的引用? – novice 2009-12-13 10:52:27

+1

@Felix。不,他正在比較引用,並且輸出是真實的 - 這正是引發此問題的稍微令人驚訝的結果。 – 2009-12-13 10:56:56

+2

正確答案? – 2009-12-13 10:57:54

5

因爲Java Language Specification說:

字符串文字,或者更一般地說, 字符串是 常量表達式(§15.28)值-are 「interned」,以便使用方法 String.intern共享唯一的 實例。

6

==檢查變量是否指向完全相同的對象實例。您創建的兩個字符串文字指向內存中的相同位置,因此它們是相同的。字符串文字是實現的,所以相同的字符串文字是內存中的同一個對象。

如果你是做

String s = new String("foo"); 
String t = new String("foo"); 

然後==將返回false和s.equals(T)將返回true。

5

這是因爲由編譯器執行的內存優化...即String常數(即 - 由同一String字面做出String S)使用相同的String對象,因爲Strings是不可改變的。 ==運算符只檢查兩個對象是否是相同的實際對象。

如果您可以通過Joshua Bloch和Neal Gafter抓住Java Puzzlers書籍,並看看拼圖13「動物農場」......他在這個問題上有很好的建議。我會複製一些相關的文字:

「你可能知道String類型是編譯時常被拘留[JLS 15.28]換句話說String類型的用於指定相同的字符序列的任意兩個常量表達式。由相同的對象引用表示...你的代碼應該很少,如果有的話,取決於字符串常量的實習。實際內部設計僅用於減少虛擬機的內存佔用量,而不是程序員的工具...在比較對象引用時,應優先使用equals方法,而不要使用==運算符,除非需要比較對象標識而不是值。」

從上述參考我提到......第30頁的 - 。31在我的書

+1

我提到這個[我沒有提到它爲什麼這麼做],我已經被拒絕了。 – monksy 2009-12-13 11:00:03

+0

+1提到Puzzlers並解釋原因 – monksy 2009-12-13 11:15:08