測試物件的等價性——"=="和"equals"
阿新 • • 發佈:2020-09-07
關係運算符== 和 !=也適用於物件。看下面這個例子:
public static void main(String[] args) {
Integer i = new Integer(1);
Integer j = new Integer(1);
System.out.println(i==j); //輸出false
System.out.println(i!=j); //輸出true
}
i的值明明等於j的值,為什麼會輸出flase?因為 ==和!=比較的是引用所指的物件是否相同。i == j表達的意思是:i這個引用指向的物件和j這個引用指向的物件是相同的嗎?i這個引用指向Integer的一個物件,j這個引用指向Integer的另一個物件。所以會輸出false。
下面我們將程式碼修改,加以驗證。
public static void main(String[] args) {
Integer i = new Integer(3);
Integer j = new Integer(1);
i = j; //我們讓其發生"別名現象",使i這個引用和j這個引用都指向j引用所指的物件。這樣它們所指的物件就相同了
System.out.println(i==j); //輸出true
}
那麼怎樣才能比較兩個物件的內容是否相同呢?這時必須使用所有物件都適用的特殊方法equals()。它是Object類中定義的方法,因為Java中所有的類都繼承於Object,因此所有的類都有這個方法。
public static void main(String[] args) {
Integer i = new Integer(1);
Integer j = new Integer(1);
System.out.println(i.equals(j)); //輸出true
}
然而事情並不總是這麼簡單,假設你建立了自己的類:
class Value{ int i; } public class Sum { public static void main(String[] args) { Value value1 = new Value(); Value value2 = new Value(); value1.i = value2.i = 100; System.out.println(value1.equals(value2));//輸出false } }
這又是怎麼回事呢?
上面已經提到了所有類都繼承於Object,我們新建的Value類也不例外,儘管表面上它沒有定義任何方法,實際上它從Object哪裡繼承了許多方法,而equals()就是其一。
至於結果為什麼會是false,這和Object類中equals()方法的實現有關,我們來看看原始碼:
public boolean equals(Object obj) {
return this == obj;
}
結果顯而易見,equals()預設行為比較的是引用是否指向同一個物件。
那麼問題又來了?
為什麼Integer的物件呼叫equals()就能得出正確答案呢?這是因為Integer類重寫了equals()方法。所以要想得到我們希望的行為,除非在自己的新類中重寫equals()方法。