再也不要對java中==和equals的區別有困惑了,這篇文章保證你能懂

想到你應該無數次看到過這個問題了,也可能你已經看過無數篇文章了,如果你還是一頭霧水或者是不理解,那試著看看這篇文章,相信你一定能看懂。

一、理解”==“的含義

在java中,主要有兩個作用。

1、基礎資料型別:比較的是他們的值是否相等,比如兩個int型別的變數,比較的是變數的值是否一樣。

2、引用資料型別:比較的是引用的地址是否相同,比如說新建了兩個User物件,比較的是兩個User的地址是否一樣。

OK。

到這就注意了,你會發現,我在舉引用的例子的時候,使用的是User物件,而不是String

。彆著急接著往下看。

二、理解equals的含義

先看看他的原始碼,equals方法是在Object中就有。

注意了這裡的原始碼是Object裡面的equals。

再也不要對java中==和equals的區別有困惑了,這篇文章保證你能懂

從這個原始碼中你會發現,比較的是當前物件的引用和obj的引用是否相同,也就是說比較的預設就是地址。還記的在上面我們使用的是User而不是String嘛?在這裡==比較的是引用的地址,equals也是比較的是引用的地址,所以他們的效果在這裡是一樣的。

再也不要對java中==和equals的區別有困惑了,這篇文章保證你能懂

現在你會發現好像equals的作用和==沒什麼區別呀,那String型別那些亂七八糟的東西是什麼呢?繼續往下看馬上揭曉。

三、重寫equals

1、String中equals方法

看到這個標題相信你已經能找到答案裡,Object物件裡面的==和equals沒有什麼區別,這樣一看equals方法存在的意義真的不大,不過後來String在Object的基礎之上重寫了equals,於是功能被大大的改變了。如何重寫的呢?我們去String的原始碼中找尋答案:

再也不要對java中==和equals的區別有困惑了,這篇文章保證你能懂

從上面的原始碼,我們能夠獲取到的資訊是:

String中的equals方法其實比較的是字串的內容是否一樣。也就是說如果像String、Date這些重寫equals的類,你可要小心了。使用的時候會和Object的不一樣。

2、測試String

看看下面的程式碼:

再也不要對java中==和equals的區別有困惑了,這篇文章保證你能懂

在上面的程式碼中,定義了三個字串,分別使用==和equals去比較。為什麼會出現這樣一個結果呢?還需要從記憶體的角度來解釋一下。

3、記憶體解釋

在java中我們一般把物件存放在堆區,把物件的引用放在棧區。因此在上面三個字串的記憶體狀態應該是下面這樣的。

再也不要對java中==和equals的區別有困惑了,這篇文章保證你能懂

現在明白了吧。

(1)String str1 = “Hello”會在堆區存放一個字串物件

(2)String str2 = new String(“Hello”)會在堆區再次存放一個字串物件

(3)String str3 = str2這時候Str3和Str2是兩個不同的引用,但是指向同一個物件。

根據這張圖再來看上面的比較:

(1)str1 == str2嘛?意思是地址指向的是同一塊地方嗎?很明顯不一樣。

(2)str1 == str3嘛?意思是地址指向的是同一塊地方嗎?很明顯不一樣。

(3)str2 == str3嘛?意思是地址指向的是同一塊地方嗎?很明顯內容一樣,所以為true。

(4)str1。equals(str2)嘛?意思是地址指向的內容一樣嘛?一樣。

(4)str1。equals(str3)嘛?意思是地址指向的內容一樣嘛?一樣。

(4)str2。equals(str3)嘛?意思是地址指向的內容一樣嘛?一樣。

OK。現在不知道你能理解嘛?

4、總結:

(1)、基礎型別比較

使用==比較值是否相等。

(2)、引用型別比較

①重寫了equals方法,比如String。

第一種情況:使用==比較的是String的引用是否指向了同一塊記憶體

第二種情況:使用equals比較的是String的引用的物件內用是否相等。

②沒有重寫equals方法,比如User等自定義類

==和equals比較的都是引用是否指向了同一塊記憶體。

5、一個小問題

當然了,String型別到這還沒結束,有一個小問題需要大家注意一下。比如看下面的程式碼:

再也不要對java中==和equals的區別有困惑了,這篇文章保證你能懂

​在這裡多了一個intern方法。他的意思是檢查字串池裡是否存在,如果存在了那就直接返回為true。因此在這裡首先s1會在字串池裡面有一個,然後 s2。intern()一看池子裡有了,就不再新建了,直接把s2指向它。