日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

“==“和equals的区别是什么(史上最全总结、最靠谱)

發布時間:2024/10/5 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 “==“和equals的区别是什么(史上最全总结、最靠谱) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2021年了,奉上我最喜歡的一句話“愿你孤獨的努力都有回報,愿你前行的路上有人陪伴”

編程是一個漫長的過程,一起加油,健康最重要,遠離ICU😁

最近突然瀏覽到了一篇“==”和“equals”的區別,突然覺得自己應該深入理解一下它們之間的區別了(哈,不找理由了,菜是原罪😀)

相信只要你學過編程,那么“==”和equals你肯定使用過,除非是專精Hello World!的大佬。

如果不查找資料你能回答出下面幾個問題呢?

你知道“==”的使用場景嗎?
你知道equals的使用場景嗎?
你知道“==”和equals的區別在哪里嗎?
你是否從底層探究過String以及包裝類重寫的equals代碼?

上面幾個問題,相信在座的大佬肯定都知道,那么請各位大佬閱讀幾分鐘,幫我這個菜鳥糾正錯誤。


八股文來了

==:對于基本類型,比較的是值是否相等;對于引用類型,比較的是地址是否相等
equals:比較的是對象是否相等(不能比較基本類型,因為equals是Object超類中的方法,而Object是所有類的父類)

因為 Java 只有值傳遞,所以,對于 == 來說,不管是比較基本數據類型,還是引用數據類型的變量,其本質比較的都是值,只是引用類型變量存的值是對象的地址。
如果你不了解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);

結果:

因為這是引用類型,所以比較的是地址是否相等,另外這也涉及到字符串常量池的概念,字符串常量池是什么呢,我怎么想不起來了呢?


哈,我怎么可能是個小丑

當創建 String 類型的對象時,虛擬機會在常量池中查找有沒有已經存在的值和要創建的值相同的對象,如果有就把它賦給當前引用。如果沒有就在常量池中重新創建一個 String 對象。

字符串常量池簡單了說就是一塊內存空間,減少重復創建字符串所需的時間,更多細節請看我的JVM專欄


分析str3==str4的結果

1、這兩個對象沒有直接使用new,所以當執行String str3=“zsh”時,字符串常量池中就會被創建一個“zsh”的字符串;
2、當執行到String str4=“zsh”,會先去常量池中查找是否有“zsh”這個字符串,如果有,則將str4也指向這個字符串;否者在常量池中創建該字符串。

那么結果為true,自然就能夠明白了。


分析str==str2的結果

這個為false應該也很簡單,new兩個對象,那么地址肯定不同;


分析str==str3的結果

一個是在字符串常量池中,一個在堆中new的對象,那么地址肯定不同了



equals來了

String str = new String("zsh");String str2 = new String("zsh");String str3 = "zsh";String str4 = "zsh";System.out.println(str3.equals(str4));System.out.println(str.equals(str2));System.out.println(str.equals(str3));


是不是感覺很奇怪,明明比較的是引用,為什么都是true呢?這就要分析String的底層代碼了

public boolean equals(Object anObject) {if (this == anObject) { //比較地址是否相等return true;}//判斷是否是String類型,如果不是,還比較個錘子,肯定false呀if (anObject instanceof String) { //轉換為本地變量String anotherString = (String)anObject;//計算字符長度,注意Java字符串末尾沒有\0,因為對象都內置的有length方法,所以不需要計算長度。int n = value.length;//如果長度不等,也不用比較了,肯定不相等if (n == anotherString.value.length) {char v1[] = value;char v2[] = anotherString.value;int i = 0;while (n-- != 0) {//核心代碼,逐個字符地比較if (v1[i] != v2[i])return false;i++;}return true;}}return false;}

核心代碼


這你應該就明白了,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));

結果:false

這個結果應該都在大家的意料之中,User類沒重寫equals方法,自然就按照地址比較了

總結

以上是生活随笔為你收集整理的“==“和equals的区别是什么(史上最全总结、最靠谱)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。