關於變量之間的比較,可以分爲基礎類型變量的比較和對象之間的比較。
對於基本類型來說,他們存儲在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。