(技術點)對象比較中equals與==的區別

關於變量之間的比較,可以分爲基礎類型變量的比較和對象之間的比較。

對於基本類型來說,他們存儲在jvm的棧中,因此比較的是變量的內容,也就是比較的變量的值。

對於引用類型來說,因爲對象內容存儲在jvm的堆中,棧中只是存儲對象的引用(地址),無論是==還是equals比較的都是棧中的內容,即對象的引用,也就是比較的是兩個對象的地址。但根據創建對象的方式不同可以分爲兩種情況:

1. 使用表達式創建對象:

2.使用new方法創建對象:

這裏會引入兩個新的問題:

1.爲什麼表達式創建和new創建,會讓==比較產生不同的結果。

這是因爲jvm在程序運行的時候會創建一個緩衝池,當使用表達式創建的時候,程序會在緩衝池中尋找相同值的對象,如果找到,就把這個對象的地址賦給當前創 建的對象,因此,c和d實際上都指向了c的引用。因此在使用==時會返回true。

當用new創建對象時,是在堆中重新分配內存,因此棧中的引用是不相同的,所以,a和b引用的是值相同的不同對象。所以a==b返回false

2.既然equals比較的是引用,那麼a.equals(b)爲什麼返回true。這是因爲在Integer裏,重寫了equals方法!

我們可以自己創建一個類,並驗證。

1.當自定義Value類中沒有重寫equals方法時,調用equals方法返回結果爲false。說明此時equals比較的並不是內容。

2.重寫equals方法。

 

總結:

比較分爲兩種情況,基本數據類型沒有 equals方法,equals方法是Object類的一個方法,比較equals和==就引用數據類型來說。

正常來說,對於引用數據類型來說,equals和==都是比較內存地址是否相同。

但是由於jvm運行時會創建一個緩存池,使用表達式創建,會在jvm緩存池中尋找相同的值的對象,在棧中同時引用這個對象,那麼,現在引用的是緩存池中的同一個對象,所以使用表達式創建,equals和==都爲true值相同。

使用new創建對象,會在java堆中創建兩個不同的對象,棧中引用這兩個對象,結果一定是不同的,所以正常來說,equals和==結果都爲false。

但是由於Integer,Date,String等重寫了equals方法,所以,使用equals比較的是值,使用equals比較值爲true。

 

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