2015-04-23 53 views
5

爲什麼...檢查對象引用相等(在Java中)

String a = new String("a"); 
    StringBuilder b = new StringBuilder("a"); 
    System.out.println(a==b); 

...導致不兼容類型的錯誤給出編譯時......

String a = new String("b"); 
    Object b = new StringBuilder("b"); 
    System.out.println(a==b); 

。 .. 纔不是?

爲什麼我可以比較一個字符串和一個對象的對象引用,而不是一個StringBuilder和一個字符串?它們不都是地址到內存位置嗎?

謝謝

+3

字符串是'對象'而不是'StringBuilder'。 – Masudul

+0

「String」和「StringBuilder」引用是否可以保存相同的實例?如果不是,那麼'a == b'測試有什麼意義?現在'Object'和'StringBuilder'引用可以保存相同的實例嗎? – Pshemo

回答

4

Acording到Java語言規範(15.21.3):

這是一個編譯時錯誤,如果它是不可能的通過轉換轉換(§5.5)將任一操作數的類型轉換爲另一個操作數的類型。兩個操作數的運行時間值必然不相等(忽略兩個值都爲空的情況)。

這意味着,爲了「比較」兩種引用類型,一種應該能夠被轉換爲另一種。字符串「是」一個對象,但在StringStringBuilder之間沒有「cast」。

+0

我將來會首先參考該規範。謝謝 – Kayl669

3

編譯器試圖幫助你。

==由於類型衝突而永遠不會成立時,它假定您犯了一個錯誤,並且會拒絕編譯代碼。

也適用於instanceof以及鑄件。

String a = null; 
if (a instanceof StringBuilder){} // compile-error 
StringBuilder b = (StringBuilder) a; // compile-error 
2

字符串擴展了Object類型,像任何其他類,但不繼承StringBuilder。因此,在您的比較String回落到Object和他們共同類型。

1

因爲Strings和StringBuilders都是Object類的子級。但它們不是同一班,所以不能使用==進行比較。您需要撥打StringBuilder上的toString方法。

0

在第二個例子中String也是一個Object,因爲所有的類都是子類Object,你可以檢查它們是否爲==。

在第一個例子中,你比較了String和StringBuilder,它們是不同的類,它們都不是另一類的子類,因此操作失敗。

3

因爲StringObjectString不是StringBuilder。您可以使用相同類型和超類型的==來比較參考。請看下面的例子現在

class A{ 

} 
class B extends A{ 

} 

class C{ 

} 

A a =new A(); 
    A b =new B(); // or B b =new B(); 
    C c= new C(); 

    System.out.println(a==b); // It is ok 
    System.out.println(a==c); // It will generate compile time error 
+0

或B b = new B();因爲提問者剛纔證明這個評論是不正確的 –

0

因爲您必須比較兼容類型,因爲比較不兼容類型的相等性始終爲false

StringObject兼容,因此將引用與這些類型進行比較不是編譯時錯誤。 StringBuilderObject兼容,因此您可以將StringBuilder分配給Object型變量。但StringStringBuilder彼此不兼容。因此,如果您有String參考號和Object參考號,則可以將它們進行比較而不會發生編譯時錯誤。但是,如果您有String引用和StringBuilder引用,則不能  —編譯器知道比較永遠不會是true

注意它是如何處理引用(變量)的類型,而不是分配給它們的對象的類型。這就是爲什麼可以設置你的第二個場景並編譯它,儘管它永遠不會有真正的結果。

相關問題