詳解Java中==和equals()的區(qū)別
1. ==
== 是運算符,用來判斷兩個值是否相等,==可以使用在基本數(shù)據(jù)類型變量和引用數(shù)據(jù)類型變量中
1.1 基本數(shù)據(jù)類型
Java基本數(shù)據(jù)類型共有八種,可以分為三類
- 字符類型char
- 布爾類型boolean
- 數(shù)值類型byte、short、int、long、float、double
這里有個例外,boolean不參與數(shù)值運算
int a1 = 10; int a2 = 10; System.out.println(a1==a2); //true float a3 = 5.0f; float a4 = 5.0f; System.out.println(a3==a4); //true ……
上面給出幾組示例,相同數(shù)據(jù)類型可以相互比較不用多說了,那么不同數(shù)據(jù)類型呢?
int a1 = 10; byte b1 = 10; System.out.println(a1==b1); //true char c1 = 'A'; int c2 = 65; System.out.println(c1 == c2); //true int a1 = 10; double d1 = 10.0d; System.out.println(a1==d1); //true int a1 = 10; char e1 = 10; System.out.println(a1==e1); //true
可以看到,在基本數(shù)據(jù)類型的范圍內(nèi),不同數(shù)據(jù)類型也是可以直接比較的
如果比較的是基本數(shù)據(jù)類型,就是判斷兩個保存的數(shù)據(jù)是否相同(不一定類型相同)
1.2 引用數(shù)據(jù)類型
這里先寫一個Student類,用于參考
public class Student { public String name; public int age; public Student(){} public Student(String name, int age){ this.name = name; this.age = age; } }
實例化兩個Student對象,判斷是否相等
Student student1 = new Student("Tom", 18); Student student2 = new Student("Tom", 18); System.out.println(student1==student2); //false
注意,這里出現(xiàn)了示例中的第一個false。可以看到,即使賦的值是相同的,但使用==判斷的結(jié)果為false,這是因為兩個對象在內(nèi)存中不指向同一地址。
如果比較的是引用類型,就是比較兩個變量是否代表同一對象實體,也就是是否指向同一地址
1.3 小結(jié)
==是運算符
可以使用在基本數(shù)據(jù)類型變量和引用數(shù)據(jù)類型變量中
如果比較的是基本數(shù)據(jù)類型,就是判斷兩個保存的數(shù)據(jù)是否相同,不一定類型相同
如果比較的是引用類型,就是比較兩個變量是否代表同一對象實體,也就是是否指向同一地址
2. equals
equals()是方法,只能用于引用數(shù)據(jù)類型
還是使用上面介紹到的Student對象,如果使用equals比較,那么?
Student student1 = new Student("Tom", 18); Student student2 = new Student("Tom", 18); System.out.println(student1.equals(student2)); //false
答案還是false,我們可以看一下在此處使用的equals的源碼
使用的正是Object中的equals()方法(繼承),而Object中的equals()方法也是使用的==進行的比較
Object類中equals()和==的作用相同
誒,部分同學(xué)可能想說了,這個equals()和我們平時用的不太一樣啊,平時用的equals()好像是用來比較數(shù)值的。這里我們拿String類來舉例。
String str1 = new String("cun"); String str2 = new String("cun"); System.out.println(str1==str2); //false System.out.println(str1.equals(str2)); //true
使用==比較,不出意外是false。而這里使用equals(),得到的結(jié)果是true。我們看一下這里的equals()源碼(Java8版本)
可以看到,String類中的equals()重寫了Object類中的equals(),這里側(cè)重于具體的數(shù)值比較(我們?nèi)粘J褂弥幸彩歉M容^具體的數(shù)值)。分析一下源碼,這里先使用==進行比較,然后判斷是否為String的一個示例,判斷長度是否相等,最后挨個判斷字符是否相等。
源碼的大部分程序都比較好理解,有些人比較迷惑這里的強制轉(zhuǎn)換(如下圖),既然前一句判斷了是否為String類的實例,后一句為什么還要強轉(zhuǎn)?這是因為,在Java中,代碼從編寫到執(zhí)行要經(jīng)歷兩個過程——編譯和執(zhí)行,在執(zhí)行時,程序判斷了實參是否為String類的實例對象,之后不再需要強轉(zhuǎn);但是在編譯中,即使經(jīng)歷了instanceof判斷,編譯器還是會始終把傳進來的參數(shù)當(dāng)作Object類型,而Object類型是沒有value屬性的,會直接報錯。所以在這里如果不強轉(zhuǎn),編譯都通不過,更不用說執(zhí)行了。
類似的,我們可以寫出Student類中重寫的equals()方法。
不過現(xiàn)在因為類使用的非常多,一方面是因為每個類都添加比較繁瑣,另一方面我們可能寫的可能不夠健壯,這里提供兩種方式自動提供equals()的重寫
IDEA編譯器的快捷鍵“alt + insert”,選擇如下圖的選項
選擇需要添加到equals()的屬性
可以看到自動生成的程序
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; return age == student.age && Objects.equals(name, student.name); }
導(dǎo)入lombok包,加入Data注解
@Data public class Student { public String name; public int age; public Student(){} public Student(String name, int age){ this.name = name; this.age = age; } }
可以看到重寫了Object類中的equals()方法
3. 總結(jié)
/** * ==是運算符,equals是方法 * 1. == * 可以使用在基本數(shù)據(jù)類型變量和引用數(shù)據(jù)類型變量中 * 如果比較的是基本數(shù)據(jù)類型,就是判斷兩個保存的數(shù)據(jù)是否相同,不一定類型相同 * 如果比較的是引用類型,就是比較兩個變量是否代表同一對象實體,也就是是否指向同一地址 * * 2. equals * 只能適用于引用數(shù)據(jù)類型 * Object類中equals()和==的作用相同 * 像String、Data、File、包裝類等中的equals都是重寫了Object類中的equals()方法,比較的是實體內(nèi)容是否相同 */
到此這篇關(guān)于Java中==和equals()的區(qū)別的文章就介紹到這了,更多相關(guān)Java ==和equals()區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java LinkedHashSet集合的底層原理和TreeSet集合
- Java中HashMap和HashSet的高效使用技巧分享
- Java中的Set接口實現(xiàn)類HashSet和LinkedHashSet詳解
- Java集合ArrayList、LinkedList、HashMap、HashSet最大容量
- Java中HashSet、LinkedHashSet和TreeSet區(qū)別詳解
- java的==運算符和equals操作詳解
- Java中==和equals()的區(qū)別總結(jié)
- java兩個integer數(shù)據(jù)判斷相等用==還是equals
- 淺談java字符串比較到底應(yīng)該用==還是equals
- java中的HashSet與 == 和 equals的區(qū)別示例解析
相關(guān)文章
Java并發(fā)Map面試線程安全數(shù)據(jù)結(jié)構(gòu)全面分析
本文將探討如何在Java中有效地應(yīng)對這些挑戰(zhàn),介紹一種強大的工具并發(fā)Map,它能夠幫助您管理多線程環(huán)境下的共享數(shù)據(jù),確保數(shù)據(jù)的一致性和高性能,深入了解Java中的并發(fā)Map實現(xiàn),包括ConcurrentHashMap和ConcurrentSkipListMap,及相關(guān)知識點2023-09-09SpringBoot2.0集成MQTT消息推送功能實現(xiàn)
這篇文章主要介紹了SpringBoot2.0集成MQTT消息推送功能實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04SSM使用mybatis分頁插件pagehepler實現(xiàn)分頁示例
本篇文章主要介紹了SSM使用mybatis分頁插件pagehepler實現(xiàn)分頁示例,使用分頁插件的原因,簡化了sql代碼的寫法,實現(xiàn)較好的物理分頁,非常具有實用價值,需要的朋友可以參考下2018-03-03從零開始學(xué)SpringBoot如何開始使用圖文詳解
這篇文章主要介紹了從零開始學(xué)SpringBoot如何開始使用,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09深入理解JVM之Java對象的創(chuàng)建、內(nèi)存布局、訪問定位詳解
這篇文章主要介紹了深入理解JVM之Java對象的創(chuàng)建、內(nèi)存布局、訪問定位,結(jié)合實例形式詳細分析了Java對象的創(chuàng)建、內(nèi)存布局、訪問定位相關(guān)概念、原理、操作技巧與注意事項,需要的朋友可以參考下2019-09-09SpringBoot安全認證Security的實現(xiàn)方法
這篇文章主要介紹了SpringBoot安全認證Security的實現(xiàn)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-05-05springboot 傳參校驗@Valid及對其的異常捕獲方式
這篇文章主要介紹了springboot 傳參校驗@Valid及對其的異常捕獲方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10