“==“和equals的区别是什么(史上最全总结、最靠谱)
2021年了,奉上我最喜歡的一句話“愿你孤獨的努力都有回報,愿你前行的路上有人陪伴”
編程是一個漫長的過程,一起加油,健康最重要,遠(yuǎn)離ICU😁
最近突然瀏覽到了一篇“==”和“equals”的區(qū)別,突然覺得自己應(yīng)該深入理解一下它們之間的區(qū)別了(哈,不找理由了,菜是原罪😀)
相信只要你學(xué)過編程,那么“==”和equals你肯定使用過,除非是專精Hello World!的大佬。
如果不查找資料你能回答出下面幾個問題呢?
| 你知道“==”的使用場景嗎? |
| 你知道equals的使用場景嗎? |
| 你知道“==”和equals的區(qū)別在哪里嗎? |
| 你是否從底層探究過String以及包裝類重寫的equals代碼? |
上面幾個問題,相信在座的大佬肯定都知道,那么請各位大佬閱讀幾分鐘,幫我這個菜鳥糾正錯誤。
八股文來了
==:對于基本類型,比較的是值是否相等;對于引用類型,比較的是地址是否相等
equals:比較的是對象是否相等(不能比較基本類型,因為equals是Object超類中的方法,而Object是所有類的父類)
因為 Java 只有值傳遞,所以,對于 == 來說,不管是比較基本數(shù)據(jù)類型,還是引用數(shù)據(jù)類型的變量,其本質(zhì)比較的都是值,只是引用類型變量存的值是對象的地址。
如果你不了解Java只有值傳遞,請看這篇文章:帶你深入理解值傳遞
==來了
看下面的例子
String str = new String("zsh");String str2 = new String("zsh");String str3 = "zsh";String str4 = "zsh";System.out.println(str3 == str4);System.out.println(str == str2);System.out.println(str == str3);結(jié)果:
因為這是引用類型,所以比較的是地址是否相等,另外這也涉及到字符串常量池的概念,字符串常量池是什么呢,我怎么想不起來了呢?
哈,我怎么可能是個小丑
當(dāng)創(chuàng)建 String 類型的對象時,虛擬機會在常量池中查找有沒有已經(jīng)存在的值和要創(chuàng)建的值相同的對象,如果有就把它賦給當(dāng)前引用。如果沒有就在常量池中重新創(chuàng)建一個 String 對象。
字符串常量池簡單了說就是一塊內(nèi)存空間,減少重復(fù)創(chuàng)建字符串所需的時間,更多細(xì)節(jié)請看我的JVM專欄
分析str3==str4的結(jié)果
1、這兩個對象沒有直接使用new,所以當(dāng)執(zhí)行String str3=“zsh”時,字符串常量池中就會被創(chuàng)建一個“zsh”的字符串;
2、當(dāng)執(zhí)行到String str4=“zsh”,會先去常量池中查找是否有“zsh”這個字符串,如果有,則將str4也指向這個字符串;否者在常量池中創(chuàng)建該字符串。
那么結(jié)果為true,自然就能夠明白了。
分析str==str2的結(jié)果
這個為false應(yīng)該也很簡單,new兩個對象,那么地址肯定不同;
分析str==str3的結(jié)果
一個是在字符串常量池中,一個在堆中new的對象,那么地址肯定不同了
equals來了
是不是感覺很奇怪,明明比較的是引用,為什么都是true呢?這就要分析String的底層代碼了
核心代碼
這你應(yīng)該就明白了,String中重寫了Object中的equals方法,并重定義了它的功能,把它改成了比較字符串是否相同。
不僅String是這樣,包裝類也是同樣如此
Integer
public boolean equals(Object obj) {if (obj instanceof Integer) { //判斷是否是Integer類型return value == ((Integer)obj).intValue();//比較值是否相等}return false;}Float
public boolean equals(Object obj) {return (obj instanceof Float)//是否滿足是Float類型和值相等&& (floatToIntBits(((Float)obj).value) == floatToIntBits(value));}Double
public boolean equals(Object obj) {return (obj instanceof Double)&& (doubleToLongBits(((Double)obj).value) ==doubleToLongBits(value));}Boolean
public boolean equals(Object obj) {if (obj instanceof Boolean) {return value == ((Boolean)obj).booleanValue();}return false;}Character
public final boolean equals(Object obj) {return (this == obj);}Long
public boolean equals(Object obj) {if (obj instanceof Long) {return value == ((Long)obj).longValue();}return false;}Boolean
public boolean equals(Object obj) {if (obj instanceof Boolean) {return value == ((Boolean)obj).booleanValue();}return false;}包裝類全部都重寫了equals方法,將其的地址比較改為了值比較。
User user = new User();user.setUsername("zsh");User user2 = new User();user2.setUsername("zsh");System.out.println(user.equals(user2));
結(jié)果:false
這個結(jié)果應(yīng)該都在大家的意料之中,User類沒重寫equals方法,自然就按照地址比較了
總結(jié)
以上是生活随笔為你收集整理的“==“和equals的区别是什么(史上最全总结、最靠谱)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 带你深入理解值传递(点进来才知道它是一篇
- 下一篇: mybatis框架中的mapper.xm