Java "equals"和"=="的區別

Java虛擬機裏有一個區域叫方法區,方法區裏有一個常量區,如果你是String str = "abc",虛擬機認爲“abc”是常量,放在常量區。下次你再定義String otherStr = “abc", 虛擬機並不新創建任何東西,而是連到剛纔常量區裏的”abc“,所以不管是equal還是==,都相等,因爲值和地址都相等。 

另外還有一個區域叫堆,如果String str = new String("abc"), 虛擬機會創建對象放到堆裏,再String otherStr = new String("abc"),會在堆裏放兩個對象。所以==就是false,因爲兩個對象地址不同。

在java程序設計中,經常需要比較兩個變量值是否相等。例如

1、簡單數據類型比較
a = 10;
b = 10;
if(a == b){
    //寫要執行的代碼
}

2、引用數據類型比較
ClassA a = new ClassA("abc");
ClassB b = new ClassB("abc");
if(a == b){
    //寫要執行的代碼
}

顯然在例1中 a == b的值爲true,例2中a == b值爲false。

下面我用int類型和它的封裝類Integer來說明簡單類型和封裝類型進行比較時的區別:==和equals()的用法。先看一段代碼:

public class TestEqual {
	public static void main(String[] args) {
		// 簡單類型比較
		int a = 100;
		int b = 100;
		System.out.println("a == b?" + (a == b));
		// 引用類型比較
		Integer c = new Integer(100);
		Integer d = new Integer(100);
		System.out.println("c == d?" + (c == d));
	}
}
運行該程序,會打印出以下信息:
a == b? true
c == b? false
可以看出,在引用類型比較中,雖然用了同一個參數“100”來構造兩個變量,但他們仍然不同。對於這兩個引用類型變量c和d,他們指向的是兩個不同的對象(只不過兩個對象的值都是100),因爲是指向兩個對象,所以比較這兩個變量會得到false的值。

注意啦,重要結論:對於引用類型變量,運算符“==”比較的是兩個變量是否引用同一對象。

那麼如何比較對象的值是否相等呢?在java中提供了equals()方法用於比較對象的值。我們把上面引用類型部分的程序稍作修改:

Integer c = new Interger(100);
Integer d = new Interger(100);
System.out.println("c equals d?" + (c.equals(d) ));
運行後可得一個true,這是因爲,方法equals()進行的是“深層比較”,他會去比較兩個對象的值是否相等。
如果你想多學一點,一定會問:“這個可愛的equals()方法是由誰來實現的呢?”
我們知道,java中所有類的父類是Object類,在Object中,已經定義了一個equals()方法,但是這個默認的equals()方法實際上也只是測試兩個變量引用是否指向同一對象(即與那個可愛的 == 功能一樣)。所以它並不一定能得到你所期望的效果。所以我們還經常需要自己將定義的類(就是上面的TestEqual)中的equals()進行覆蓋。像Integer封裝類就已經覆蓋了Object中的equals()方法,直接可以拿來比較引用類型c和d指向的對象的值。

好了,相信你一定耐心地看到了這裏,我們來總結一下== 和equals()兩種比較方法,在使用時要注意:
1、如果測試兩個簡單類型的數值是否相等,則一定要用“==”來比較;
2、如果要比較兩個引用變量對象的值是否相等,則要用對象的equals()方法進行比較;
3、如果需要比較兩個引用變量是否指向同一對象,則使用“==”來進行比較;

還有,對於自定義的類,應該根據情況覆蓋其父類或Object類中的equals()方法,否則默認的equals()方法功能與“==”相同。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章