淺析java中String類型中“==”與“equal”的區(qū)別
一、前言
1.1、首先很多人都知道,String中用“==”比較的是地址,用equals比較的是內(nèi)容,很多人對(duì)此用的是記憶法,通過(guò)記憶來(lái)加強(qiáng)此的引用,但是其真正的原理其實(shí)并不難,當(dāng)我們真正明白其為什么的時(shí)候,用起來(lái)也會(huì)更加靈活,更加有底氣(形容得不太好,朋友別見(jiàn)怪);
二相關(guān)知識(shí)的準(zhǔn)備
- 類型常量池
- 運(yùn)行時(shí)常量池
- 字符串常量池
我們今天討論的主題是當(dāng)然是字符串常量池:
為什么在這要把另外兩個(gè)常量池拿出說(shuō)一下呢,首先小生我在網(wǎng)上或者cnds上看到很多人在爭(zhēng)論字符串常量池是存在與方法區(qū)還是堆里面,因此我在這里面非常負(fù)責(zé)任的告訴各位讀者:
1、類型常量池,存放在方法區(qū)里面,每個(gè)class文件都有一個(gè)
2、運(yùn)行時(shí)常量池、存放在方法區(qū)里面,所有class共用
3、字符串常量池:存放在堆區(qū)里面
而且字符串常量池有一個(gè)特點(diǎn):存放的常量唯一:三、 開(kāi)始
3.1,情況一
public class Test2 { public static void main(String[] args) { String a ="張敬軒"; String b ="張敬軒"; System.out.println(a == b); System.out.println(a.equals(b)); } }
運(yùn)行結(jié)果:
- true
- true
解釋:因?yàn)楫?dāng)我們String a = “張敬軒”;的時(shí)候,會(huì)在堆里面的字符串常量池里面“搜索”是否有“張敬軒”這個(gè)對(duì)象,
- 有:就會(huì)將“張敬軒這個(gè)對(duì)象的地址指向a”
- 沒(méi)有:就會(huì)在字符串常量池里面新建立一個(gè)“張敬軒”,然后就會(huì)把地址引用賦值給a
當(dāng)再聲明String b = “張敬軒";和第一次聲明String = “張敬軒”;一樣,先”搜索“,然后因?yàn)橐呀?jīng)存在了”張敬軒“這個(gè)對(duì)象,那么就不會(huì)再創(chuàng)建對(duì)象,而是將存在的”張敬軒“的地址引用賦值給b,所以
a和b的地址一樣,內(nèi)容自然也一樣,所以兩個(gè)結(jié)果為true,不懂各位朋友懂沒(méi)懂?
3.2,情況二;
public class Test2 { public static void main(String[] args) { String a ="張敬軒"; String b = new String("張敬軒"); System.out.println(a == b); System.out.println(a.equals(b)); } }
結(jié)果是
false,true
解釋
String a = “張敬軒”;
已經(jīng)解釋過(guò)了,是在堆里面的字符串常量池創(chuàng)建對(duì)象
String b = new String(“張敬軒”);
這個(gè)也是在堆區(qū)里面創(chuàng)建對(duì)象,但是不是在字符串常量池里面創(chuàng)建對(duì)象
兩個(gè)不同的對(duì)象,地址自然不同,類容都是張敬軒,所以結(jié)果是false,true
3.3、情況三
public class Test2 { public static void main(String[] args) { String a = new String("張敬軒"); String b = new String("張敬軒"); System.out.println(a == b); System.out.println(a.equals(b)); } }
結(jié)果:false,true
解釋,因?yàn)閚ew (“張敬軒”);表示在堆區(qū)的非字符串常量池里面創(chuàng)建了兩個(gè)不同的對(duì)象,兩次new就創(chuàng)建了兩個(gè),所以地址是不同的,因此結(jié)果是false,true
3.4、情況四
public class Test2 { public static void main(String[] args) { String a = "張"+"敬軒"; String b = "張敬軒"; System.out.println(a == b); System.out.println(a.equals(b)); } }
結(jié)果是:true,true
解釋:String = “張敬” + ”軒“;
在編譯的時(shí)候就已經(jīng)開(kāi)始進(jìn)行計(jì)算:這是Java編譯的優(yōu)化機(jī)制,所以a指向的地址依舊是”張敬軒“;所以情況和前面的情況一一致,所以是true,true
(注意Java編譯優(yōu)化機(jī)制只針對(duì)常量不針對(duì)變量 a = a+ b(這個(gè)是沒(méi)有優(yōu)化機(jī)制的,關(guān)于Java編譯機(jī)制,各位小伙伴可以去百度了解一下))
3.5、情況五
public class Test2 { public static void main(String[] args) { String a = "張"; String b = "敬軒"; String c =a+b; String d = "張敬軒"; System.out.println(d == c); System.out.println(d.equals(c)); } }
結(jié)果:
解釋:因?yàn)閍 和 b是變量,不存在什么Java優(yōu)化機(jī)制,而是將兩個(gè)c = a + b存放在的是堆區(qū)的非字符常量池里面,所以是兩個(gè)不同的對(duì)象,自然為false,true
3.6、最后一種情況
public class Test2 { public static void main(String[] args) { String a = "張"; String b = "敬軒"; String c =(a+b).intern(); String d = "張敬軒"; System.out.println(d == c); System.out.println(d.equals(c)); } }
結(jié)果:
解釋:intern();方法是將堆區(qū)里面的非字符常量池里面的對(duì)象強(qiáng)行放到字符常量池里面,因?yàn)樽址A砍乩锩鎸?duì)象的唯一性,如果字符串常量池里面已經(jīng)有了和”張敬軒“一樣的對(duì)象,就會(huì)將其地址引用賦值給c,沒(méi)有就相當(dāng)于創(chuàng)建一個(gè)(也就是和之前堆區(qū)里面那個(gè)對(duì)象一樣的對(duì)象),有了的話,就會(huì)將原來(lái)有的那個(gè)“張敬軒”對(duì)象賦值給c,因?yàn)榈刂芬粯樱詾閠rue
總結(jié):
== 比較的地址 (如果對(duì)象存在字符串常量池,而且類容相同,那么 == 返回的是true )
equal 比較的是內(nèi)容 (內(nèi)容相同返回便是true)(所以在以后的開(kāi)發(fā)中一般是用equal比較字符串的)
各位朋友如果有錯(cuò)的及時(shí)評(píng)論區(qū)指出,謝謝大家的支持
到此這篇關(guān)于淺析java中String類型中“==”與“equal”的區(qū)別的文章就介紹到這了,更多相關(guān)java String類型 ==與equal內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java中char數(shù)組(字符數(shù)組)與字符串String類型的轉(zhuǎn)換方法
- 簡(jiǎn)單談?wù)凧ava中String類型的參數(shù)傳遞問(wèn)題
- JAVA中string數(shù)據(jù)類型轉(zhuǎn)換詳解
- java對(duì)象轉(zhuǎn)換String類型的三種方法
- Java中==符號(hào)與equals()的使用詳解(測(cè)試兩個(gè)變量是否相等)
- 基于Java字符串 "==" 與 "equals" 的深入理解
- java中equals和等號(hào)(==)的區(qū)別淺談
- java String 類的一些理解 關(guān)于==、equals、null
相關(guān)文章
spring boot使用sharding jdbc的配置方式
這篇文章主要介紹了spring boot使用sharding jdbc的配置方式,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12spring mail借助qq郵箱服務(wù)器發(fā)送郵件
這篇文章主要介紹了spring mail借助qq郵箱服務(wù)器發(fā)送郵件的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12使用SpringBoot+OkHttp+fastjson實(shí)現(xiàn)Github的OAuth第三方登錄
這篇文章主要介紹了使用SpringBoot+OkHttp+fastjson實(shí)現(xiàn)Github的OAuth第三方登錄,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02單臺(tái)Spring Cloud Eureka升級(jí)到三臺(tái)Eureka高可用集群
今天小編就為大家分享一篇關(guān)于單臺(tái)Spring Cloud Eureka升級(jí)到三臺(tái)Eureka高可用集群,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-12-12springboot動(dòng)態(tài)加載Echarts柱狀圖
這篇文章主要為大家詳細(xì)介紹了springboot動(dòng)態(tài)加載Echarts柱狀圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12Reactor定制一個(gè)生產(chǎn)的WebClient實(shí)現(xiàn)示例
這篇文章主要為大家介紹了Reactor定制一個(gè)生產(chǎn)的WebClient實(shí)現(xiàn)示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08簡(jiǎn)介Java的Spring框架的體系結(jié)構(gòu)以及安裝配置
這篇文章主要介紹了Java的Spring框架的體系結(jié)構(gòu)以及安裝配置,Spring框架是Java的SSH三大web開(kāi)發(fā)框架之一,需要的朋友可以參考下2015-12-12Springboot內(nèi)置Tomcat配置參數(shù)調(diào)優(yōu)方式
這篇文章主要介紹了Springboot內(nèi)置Tomcat配置參數(shù)調(diào)優(yōu)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06利用javadoc注釋自動(dòng)生成Swagger注解
由于現(xiàn)在controller方法上面沒(méi)有swagger注解,只能拿到接口url地址,無(wú)法獲得接口功能描述,所以本文為大家介紹一下如何利用javadoc注釋自動(dòng)生成Swagger注解,感興趣的可以了解下2023-08-08