首先籠統的來講 “java中equals()方法和“==”運算符” 都是比較的地址,那爲什麼我們在使用中總會出現混淆的情況呢老是弄錯呢,這是因爲“重寫equals()方法”和一些
“特殊情況”的存在
- 由於java中的所有的類都是默認的繼承自Object類的,那我們看一下Object類中equals方式是怎麼定義的:
public boolean equals(Object obj) {
return (this == obj);
}
發現了吧,Object類中equals方法 就等於 “==”,比較的是對象的地址是否是一樣的。(周所衆知 “==”運算符如果操作的是原子類型的話比較的是值,操作的是對象的話則是對象的地址)
2. 但是在實際的使用中 equals方法和“==”運算符的執行結果卻不盡相同 這是爲什麼呢?舉個例子:
String a=new String("abc");
String b=new String("abc");
a.equals(b) ;//結果是true
a==b;//結果卻是false
這是爲什麼呢? 不是1中說了equals方法和“==”比較結果是一致的麼,由於在這裏a和b都是String對象,在1中說過了 所有的類都繼承自Object類,那麼在String類中那麼也應該有一個equals方法,那麼我們就去看一下他的equals方法是怎麼定義的
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
看到這裏相信大夥兒明白了吧,原來String類重寫了Object類的equals方法,重新定義了equals方法的比較規則,首先判斷兩個對象的地址是否是一樣的, 是一樣的話那肯定”相等“ 否則的話就一個一個的比較String裏面的每一個字符,總的起來說String類的equals方法比較的就是字符串的”值“。而“==”運算法比較的是對象的地址,顯然a和b是兩個不同的對象,比較結果當然是false了。
3. 在說一個特殊情況,比較原子類型的時候 java的“==”運算符比較的是 原子類型的值(且只能用“==”運算符來比較,爲什麼不能用equals方法來比較請看1中在Object類中equals方法的定義(注意方法的參數類型是Object,顯然原子類型不是Object的子類)) 舉例如下:
int a=1;
int b=1;
a==b//true
4. 綜上所述如果我們自定義類型時如果需要比較這個類型的對象是否相等那就應該重新定義繼承自Object類的equals方法,例如
class Cat{
private String name;
private int age;
@Override
public boolean equals(Object obj) {
if(null==obj)return false;
if(obj==this)return true;
if(getClass()!=obj.getClass())return false;
else{
Cat c=(Cat)obj;
return name.equals(c.name)&& (age==c.age);
}
}
}
可以像上面這樣來寫,當然了,關鍵得看自己怎麼定義“相等”這個概念了