2009-12-01 23 views
2

這是一個Java和C#問題。我們都知道,Object Identity(==)測試兩個對象是否引用相同的位置,Obejct Equality(Equals方法)測試兩個不同的(不同的)對象是否具有相同的值。但是在字符串對象對象標識和對象平等是相同的。 對於e.g下面兩個布爾表達式中的if語句返回true關於對象標識和對象相等和字符串類異常的問題

string a="123"; 
string b="123"; 
if(a==b) 
if(a.Equals(b)) 

爲什麼會這樣? 這個設計決定背後的理由是什麼?

+0

我建議你閱讀的Object.Equals()和String.equals(代碼),你會看到這是不正確的。 –

+0

在C#中,「==」不被視爲IDENTITY測試。它通常被用來做任何類的EQUALS方法。 「ReferenceEquals(a,b)」是.Net的IDENTITY測試。 – ToolmakerSteve

回答

4

Java和C#都使用稱爲string interning的存儲節省技術。由於字符串在這些語言中是不可變的,因此它們可以彙集經常使用的字符串(包括硬編碼字符串文字,如您的示例中所示),並使用多個對內存中的一個字符串的引用來節省空間。

2

實際上,至少在Java中,有一個字符串緩存機制。一個陷阱就是有時候兩個相等的字符串會相同,但在應用身份運算符時並不總是返回true。下面的代碼打印假:

String a="123"; 
String b="12"; 
b=b+"3"; 
System.out.println(a==b); 
0

如果你真的想確保,即a.equals(b) == true(a==b) == false計算爲false兩個字符串a和b,那麼你可以使用完全被低估的(^^)String構造:

String a = new String("abc"); 
String b = new String("abc"); 
if (a.equals(b)) { 
    doTheyAreEqual(); 
    if (a != b) { 
    doButNotTheSame(); 
    } 
} 
+0

在C#中,這些都將評估爲「true」。 ReferenceEquals(a,b)將評估爲'false'。 – ToolmakerSteve

2

據我所知,在.net中,用於字符串的==運算符被重載爲使用Equals()而不是對象標識。看到這個解釋的細節:http://www.dotnetperls.com/string-equals

因爲如果你需要知道它的真正同一個對象,使用此:

Object.ReferenceEquals(string1, string2)