大概說equals和==都比較的是什么:
1. boolean tem = a == b;
首先==比較的肯定是地址(和hashcade沒有關系,hashcade不同說明不是一個對象,但是兩個不一樣的對象hashcode也有可能相同。比如兩個內容相同的String對象),從堆棧的角度說也就是說==比較的是棧上面的內容。因為棧是用來存放地址或是java中八大基本類型中自動變量的字面值(自動變量就是用int a = 1;這種形式來定義的變量)。如果是自動變量比較值的話肯定是用==來比較,因為equals()是一個方法,所以必須由對象調用才可以用於比較。而自動變量既不是類的實例也不是類的引用所以不能用equals()方法。
2.boolean tem = a.equals("b");
equals()方法一般用於比較的是對象的內容但是也有的情況下也會去比較兩個對象的地址。
接下來
寫一個測試程序
package com;
import java.util.Date;
public class test {
public static void main(String[] args) {
Integer integer1 = new Integer(1);
Integer integer2 = new Integer(1);
String str1 = new String("123");
String str2 = new String("123");
String str3 = "abc";
String str4 = "abc";
Date date1 = new Date();
Date date2 = new Date();
Double double1 = new Double("1.0");
Double double2 = new Double("1.0");
Boolean tem1 = new Boolean(true);
Boolean tem2 = new Boolean(true);
Object object1 = new Object();
Object object2 = new Object();
System.out.println("----Object------");
System.out.println(object1.equals(object2));
System.out.println(object1 == object2);
System.out.println(object1.equals(object1));
System.out.println(object1 == object1);
System.out.println("----Boolean------");
System.out.println(tem1.equals(tem2));
System.out.println(tem1 == tem2);
System.out.println("----Double------");
System.out.println(double1.equals(double2));
System.out.println(double1 == double2);
System.out.println("----Integer------");
System.out.println(integer1.equals(integer2));
System.out.println(integer1 == integer2);
System.out.println("----String------");
System.out.println(str1.equals(str2));
System.out.println(str1 == str2);
System.out.println(str1.equals(str2)); System.out.println(str1 == str2)System.out.println(str3.equals(str4));
System.out.println(str3 == str4);
System.out.println("----Date------");
System.out.println(date1.equals(date2));
System.out.println(date1 == date2);
}
}
結果:
----Object------
false
false
true
true
----Boolean------
true
false
----Double------
true
false
----Integer------
true
false
----String------
true
false
true
true
----Date------
true
false
首先對Object的比較,當比較的兩個對象一樣時,==和equals()的結果都是true,當兩個對象不一樣時返回的都是false。所以在==和equals用於比較對象時,他們比較的都是對象的地址,其實本質是一樣的。下面是Object類中equals()方法的代碼:
public boolean equals(Object obj) { return (this == obj); }
在這里string需要特殊說明一下,我們知道String是被final修飾的是不可變的,這時候我們可能會想== 不是用來比較引用嗎,那為什么str3 == str4還能等於true呢?注意“==”的確用來比較對象的引用,但是你能夠確定String str3 = "abc";和String str4 = "abc";重新生成對象了嗎?原來java在String這塊也做了特殊處理,在這塊有個叫做字符緩沖池的東西,當用new的方法創建一個string對象時會先在字符串緩沖池中找有沒有和新創建的字符串內容相等的對象,如果沒有的話就會在緩沖池新創建一個字符串對象然后再在堆中創建字符串對象,如果緩沖池中已經有了和新創建的字符串內容相等的對象就會直接在堆上新創建對象。如果不用new的方式也是先會看緩沖池中有沒有創建過這個對象,如果沒有創建就在里邊創建一個,如果已經創建了那新聲明的引用(例子中的str4)就會直接指向這個對象。所以在本例中str3 == str4 是等於true。關於string的知識需要注意的不只有這些,想要了解的同學再留言討論吧。這里我們主要說equals和==的區別。
而對於Boolean,Double(Float同理),Interger(Shot,Long同理),String,Date我也找了他們的源碼,下面我依次貼出來在Boolean,Double,Interger,String,Date這些類中equals()方法的源碼,這時候equals()方法就被重寫了,因為這些類都是繼承於Object類的嘛。
Boolean:
public boolean equals(Object obj) { if (obj instanceof Boolean) { return value == ((Boolean)obj).booleanValue(); } return false; }
Double:
public boolean equals(Object obj) { return (obj instanceof Double) && (doubleToLongBits(((Double)obj).value) == doubleToLongBits(value)); }
Interger:
public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; }
String:
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String) anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
Date:
public boolean equals(Object obj) { return obj instanceof Date && getTime() == ((Date) obj).getTime(); }
也就是說在這些時候重寫了Object類的equals()方法用於比較兩個對象實際的內容而不再是地址了,當然肯定不只是這些,這里只是舉出了幾個比較常見的java原生類重寫Object類的equals()方法的情況。