那么,應該怎么比較兩個對象的值而不是比較它們的引用呢?Java(TM) 編程語言有一個約定,方法 equals() 用來定義對象值相等。 類 Object 中定義了方法equals(),如果在其子類中沒有被重載,那么默認使用的是它。 為了比較兩只狗(dog) a 和 b 的值,你應該重寫上面的比較部分:
if ( a.equals(b) ) {
System.out.println("a is equals() to b");
}
else {
System.out.println("a is not equals() to b");
}
上面的代碼中,如果在 Dog 中沒有重載 equals() 方法,兩只狗依舊不等。因為 Object.equals() 實際模擬的是 == 操作符的功能。 Dog 中 equals() 的定義很好懂:
class Dog {
int tag;
int age;
public void setTag(int t) {tag=t;}
public void setAge(int a) {age=a;}
public boolean equals(Object o) {
Dog d = (Dog)o;
if ( tag==d.tag && age==d.age ) {
return true;
}
return false;
}
}
為什么 equals() 的參數(shù)類型是 Object 而不是 Dog 呢?因為你是在重載父類 Object 的方法 equals(),所以必須用相同的方法標記。但我們希望傳進的參數(shù)是另一只Dog,所以為了能夠訪問參數(shù)的字段需將其類型轉換為 Dog。
但是,由于 equals() 是在 Dog 中定義的,你必須檢查傳入的對象是否是一只 Dog,因為有人可能這樣用:
fido.equals("blort");
字符串 "blort" 也是一個 Object ,因此與 Dog 中 equals() 的標記是匹配的。equals() 的正確寫法是:
public boolean equals(Object o) {
if ( o instanceof Dog ) {
Dog d = (Dog)o;
if ( tag==d.tag && age==d.age ) {
return true;
}
}
// false if not Dog or contents mismatched
return false;
}
操作符 instanceof 詢問 o 是否是 Dog (包括 Dog 的子類) 的實例。
字符串的比較引入了對象比較的后一個問題,那是
"abc"=="def"
表達式的值為 true 還是 false 呢?是false,因為他們是本質都不同的對象(顯而易見,他們的內(nèi)容都不同)。但是,下面的表達式
"abc"=="abc"
是 true 還是 false 呢?不幸的是,這由編譯器決定。如果編譯器將對 "abc" 的兩個引用優(yōu)化為一個對象而不是兩個對象,那么表達式的值為 true。但是,如果編譯器不做這種優(yōu)化,表達式的值則應為 false!
如果你真的想判斷兩個字符串在物理上是不是同一個對象,請用 equals() 方法:
boolean b = "abc".equals("def"); // false
boolean c = "abc".equals("abc"); // true
根據(jù)上面得方法,然后用assertTrue即可完成兩個對象的比較。