Java中equals與==的用法和區(qū)別
背景介紹
== 比較的是變量(棧)內(nèi)存中存放的對(duì)象的(堆)內(nèi)存地址,用來(lái)判斷兩個(gè)對(duì)象的地址是否相同,即是否是指相同一個(gè)對(duì)象。比較的是真正意義上的指針操作。
equals用來(lái)比較的是兩個(gè)對(duì)象的內(nèi)容是否相等,由于所有的類都是繼承自java.lang.Object類的,所以適用于所有對(duì)象,如果沒(méi)有對(duì)該方法進(jìn)行覆蓋的話,調(diào)用的仍然是Object類中的方法,而Object中的equals方法返回的卻是==的判斷。
java中的數(shù)據(jù)類型可以分為兩類:
基本數(shù)據(jù)類型
byte,short,char,int,long,float,double,boolean
基本數(shù)據(jù)類型之間的比較需要用雙等號(hào)(==),因?yàn)樗麄儽容^的是值
引用數(shù)據(jù)類型
接口、類、數(shù)組等非基本數(shù)據(jù)類型
Java中的字符串String屬于引用數(shù)據(jù)類型。因?yàn)镾tring是一個(gè)類
當(dāng)他們用(==)進(jìn)行比較的時(shí)候,比較的是他們?cè)趦?nèi)存中的存放地址,所以,除非是同一個(gè)new出來(lái)的對(duì)象,他們的比較后的結(jié)果為true,否則比較后結(jié)果為false。因?yàn)闆](méi)new一次就會(huì)重新開(kāi)辟一個(gè)新的堆內(nèi)存空間
Entity entity = new Entity(); Entity entity1 = new Entity(); Entity entity2 = entity; System.out.println(entity==entity2); System.out.println(entity.equals(entity2)); System.out.println(entity.equals(entity1)); System.out.println(entity==entity1);
執(zhí)行結(jié)果
true
true
false
false
equals()方法介紹
Java中所有的類都是繼承與Object這個(gè)基類的,在Object類中定義了一個(gè)equals方法,這個(gè)方法的初始行為是比較對(duì)象的內(nèi)存地址,但在一些類庫(kù)中已經(jīng)重寫了這個(gè)方法(一般都是用來(lái)比較對(duì)象的成員變量值是否相同),比如:String,Integer,Date 等類中,所以他們不再是比較類在堆中的地址了、
Object類中源碼
public boolean equals(Object var1) { return this == var1; }
String類中重寫后的代碼
public boolean equals(Object var1) { if (this == var1) { return true; } else { if (var1 instanceof String) { String var2 = (String)var1; int var3 = this.value.length; if (var3 == var2.value.length) { char[] var4 = this.value; char[] var5 = var2.value; for(int var6 = 0; var3-- != 0; ++var6) { if (var4[var6] != var5[var6]) { return false; } } return true; } } return false; } }
總結(jié):
對(duì)于復(fù)合數(shù)據(jù)類型之間進(jìn)行equals比較,在沒(méi)有覆寫equals方法的情況下,他們之間的比較還是內(nèi)存中的存放位置的地址值,跟雙等號(hào)(==)的結(jié)果相同;如果被復(fù)寫,按照復(fù)寫的要求來(lái)。
== 的作用:
基本類型:比較的就是值是否相同
引用類型:比較的就是地址值是否相同
equals 的作用:
引用類型:默認(rèn)情況下,比較的是地址值,重寫該方法后比較對(duì)象的成員變量值是否相同
String類的equals()方法
在之前文章介紹JVM的時(shí)候,提到過(guò)一個(gè)常量池,這里咱們?cè)賮?lái)介紹下
String a = "abc";// abc在常量池中 String b = "abc";//棧中b指向常量池中的abc String c = new String("abc");// 在堆內(nèi)存中重新開(kāi)辟了一個(gè)abc的空間 String d = c.intern();//檢查字符串池里是否存在"abc"這么一個(gè)字符串,如果存在,就返回池里的字符串;如果不存在,該方法會(huì) 把"abc"添加到字符串池中,然后再返回它的引用。 System.out.println(a==b); System.out.println(a.equals(b)); System.out.println(a==c); System.out.println(a.equals(c)); System.out.println(a==d); System.out.println(a.equals(d));
true
true
false
true
true
true
關(guān)于常量池的描述可以看我這篇文章: 深入java虛擬機(jī)學(xué)習(xí) -- 內(nèi)存管理機(jī)制
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
Spring復(fù)雜對(duì)象創(chuàng)建的方式小結(jié)
這篇文章主要介紹了Spring復(fù)雜對(duì)象創(chuàng)建的三種方式,現(xiàn)在使用Spring如何創(chuàng)建這種類型的對(duì)象?Spring中提供了三種方法來(lái)創(chuàng)建復(fù)雜對(duì)象,需要的朋友可以參考下2022-01-01Spring Boot 實(shí)現(xiàn)程序的優(yōu)雅退出(詳細(xì)步驟)
Spring Boot 為我們提供了優(yōu)雅退出的功能,使應(yīng)用程序能夠在關(guān)閉時(shí)正常處理完所有當(dāng)前請(qǐng)求,避免請(qǐng)求被中斷導(dǎo)致數(shù)據(jù)丟失或不一致等問(wèn)題,本文將全面介紹如何在 Spring Boot 應(yīng)用程序中實(shí)現(xiàn)優(yōu)雅退出,感興趣的朋友跟隨小編一起看看吧2024-03-03Springboot如何添加server.servlet.context-path相關(guān)使用
這篇文章主要介紹了Springboot如何添加server.servlet.context-path相關(guān)使用問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03SpringBoot項(xiàng)目中Redis存儲(chǔ)Session對(duì)象序列化處理
在 Spring Boot 項(xiàng)目中使用 Redis 存儲(chǔ) Session 時(shí),對(duì)象的序列化和反序列化是關(guān)鍵步驟,下面我們就來(lái)講講如何在 Spring Boot 項(xiàng)目中處理 Redis 存儲(chǔ) Session 對(duì)象的序列化和反序列化吧2025-05-05深入理解Java8新特性之Stream API的終止操作步驟
Stream是Java8的一大亮點(diǎn),是對(duì)容器對(duì)象功能的增強(qiáng),它專注于對(duì)容器對(duì)象進(jìn)行各種非常便利、高效的 聚合操作(aggregate operation)或者大批量數(shù)據(jù)操作。Stream API借助于同樣新出現(xiàn)的Lambda表達(dá)式,極大的提高編程效率和程序可讀性,感興趣的朋友快來(lái)看看吧2021-11-11