java String類常量池分析及"equals"和"==”區(qū)別詳細(xì)介紹
java "equals"和"==”異同
首先簡(jiǎn)單說(shuō)一下“equal”和“==”
==操作對(duì)于基本數(shù)據(jù)類型比較的是兩個(gè)變量的值是否相等,
對(duì)于引用型變量表示的是兩個(gè)變量在堆中存儲(chǔ)的地址是否相同,
即棧中的內(nèi)容是否相同
equals操作表示的兩個(gè)變量是否是對(duì)同一個(gè)對(duì)象的引用,
即堆中的內(nèi)容是否相同。
綜上,==比較的是2個(gè)對(duì)象的地址,而equals比較的是2個(gè)對(duì)象的內(nèi)容。
再簡(jiǎn)單介紹一下String類
String類 又稱作不可變字符序列
String使用private final char value[]來(lái)實(shí)現(xiàn)字符串的存儲(chǔ),也就是說(shuō)String對(duì)象創(chuàng)建之后,就不能再修改此對(duì)象中存儲(chǔ)的字符串內(nèi)容。String類有一個(gè)特殊的創(chuàng)建方法,就是使用""雙引號(hào)來(lái)創(chuàng)建。例如new String("123")實(shí)際創(chuàng)建了2個(gè)String對(duì)象,一個(gè)是"123"通過(guò)""雙引號(hào)創(chuàng)建的,另一個(gè)是通過(guò)new創(chuàng)建的.只不過(guò)他們創(chuàng)建的時(shí)期不同,一個(gè)是編譯期,一個(gè)是運(yùn)行期。java對(duì)String類型重載了+操作符,可以直接使用+對(duì)兩個(gè)字符串進(jìn)行連接。運(yùn)行期調(diào)用String類的intern()方法可以向String Pool中動(dòng)態(tài)添加對(duì)象。
區(qū)分兩種創(chuàng)建String對(duì)象的方法“”和new()
String是一個(gè)特殊的包裝類數(shù)據(jù)??梢杂茫?br />
String str1 = new String("123"); String str2 = "123";
兩種的形式來(lái)創(chuàng)建
第一種是用new()來(lái)新建對(duì)象的,它會(huì)在存放于堆中。每調(diào)用一次就會(huì)創(chuàng)建一個(gè)新的對(duì)象。(實(shí)際是兩個(gè)正如上文所說(shuō),但是在常量池中存在“123”后就不會(huì)再在常量池中創(chuàng)建新的“123”)
第二種是先在棧中創(chuàng)建一個(gè)對(duì)String類的對(duì)象引用變量str,然后通過(guò)符號(hào)引用去字符串常量池里找有沒有"abc",如果沒有,則將"abc"存放進(jìn)字符串常量池,并令str指向”abc”,如果已經(jīng)有”abc”則直接令str指向“abc”。
這時(shí)我們應(yīng)該注意
一方面,第一種寫法有利與節(jié)省內(nèi)存空間.同時(shí)它可以在一定程度上提高程序的運(yùn)行速度,因?yàn)镴VM會(huì)自動(dòng)根據(jù)棧中數(shù)據(jù)的實(shí)際情況來(lái)決定是否有必要?jiǎng)?chuàng)建新對(duì)象。而對(duì)于String str = new String("123");的代碼,則一概在堆中創(chuàng)建新對(duì)象,而不管其字符串值是否相等,是否有必要?jiǎng)?chuàng)建新對(duì)象,從而加重了程序的負(fù)擔(dān)。另一方面,我們?cè)谑褂弥T如String str = "123";的格式定義類時(shí),總是想當(dāng)然地認(rèn)為,創(chuàng)建了String類的對(duì)象str。
對(duì)象可能并沒有被創(chuàng)建!而可能只是指向一個(gè)先前已經(jīng)創(chuàng)建的對(duì)象。只有通過(guò)new()方法才能保證每次都創(chuàng)建一個(gè)新的對(duì)象。
請(qǐng)看下列實(shí)例
package testString; public class testString { public static void main(String[] args) { String a = "123"; String b = "123"; System.out.println(a==b); System.out.println(a.equals(b)); System.out.println("------------------------------------------"); /** * true * true * 此處創(chuàng)建一個(gè)字符串"123"儲(chǔ)存在常量池中 * 因?yàn)?123"儲(chǔ)存在常量區(qū),并且唯一,即兩個(gè)String引用a和b所的地址相同所以a==b為true * 并且兩個(gè)引用在所指對(duì)象在堆中的內(nèi)容相同所以a.equals(b)為true */ String c = new String("1234"); String d = new String("1234"); System.out.println(c==d); System.out.println(c.equals(d)); System.out.println("------------------------------------------"); /* * false * true * 此處創(chuàng)建三個(gè)字符串“1234”,一個(gè)在常量池中,兩個(gè)通過(guò)new儲(chǔ)存在堆中 * 因?yàn)閏和d此時(shí)指向的是堆中的兩個(gè)String對(duì)象,所以地址不同 c==d為false * 但是c與d堆中內(nèi)容相同所以c.equals(d)為true */ String e = "a1"; String f = "a"+1; System.out.println(e==f); System.out.println(e.equals(f)); System.out.println("------------------------------------------"); /** * true * true * 此處創(chuàng)建“a1”“a”2個(gè)字符串其中“a1”“a”他們兩個(gè)均在常量池中,你可能會(huì)問(wèn)+是個(gè)運(yùn)算符重載么? * 是的,java自己有一定的運(yùn)算符重載但是你沒法使用定義自己的運(yùn)算符重載,和c++不同,String f = "a"+1; * 這句會(huì)被編譯器做成 String f=“a1”;這與我們講到的第一種情況相同,不再贅述。 * 編譯器之所以這么做是因?yàn)樗诰幾g時(shí)就能夠確定 */ String g = "gh"; String hh = "h"; String h = "g" + hh ; System.out.println(g==h); System.out.println(g.equals(h)); System.out.println("------------------------------------------"); /** * false * true * 與上面不同的是這里的h在編譯時(shí)不能確定(編譯器是這樣認(rèn)為的),所以h所指的對(duì)象在運(yùn)行時(shí)確定儲(chǔ)存在堆中, * 所以g==h為true而g.equals(h)為false */ } }
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
SpringBoot集成Redisson操作Redis的實(shí)現(xiàn)方法
Redisson是一個(gè)用于Java的Redis客戶端,它提供了在分布式環(huán)境下操作Redis數(shù)據(jù)庫(kù)的簡(jiǎn)單、高效的方式,本文主要介紹了SpringBoot集成Redisson操作Redis的實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03使用Spring?Boot進(jìn)行單元測(cè)試詳情
這篇文章主要介紹了使用Spring?Boot進(jìn)行單元測(cè)試詳情,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09Spring中property-placeholder的使用與解析詳解
本篇文章主要介紹了Spring中property-placeholder的使用與解析詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05Java實(shí)現(xiàn)簡(jiǎn)單控制臺(tái)版ATM系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)單控制臺(tái)版ATM系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05解決SpringMVC Controller 接收頁(yè)面?zhèn)鬟f的中文參數(shù)出現(xiàn)亂碼的問(wèn)題
下面小編就為大家分享一篇解決SpringMVC Controller 接收頁(yè)面?zhèn)鬟f的中文參數(shù)出現(xiàn)亂碼的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03Java C++解決在排序數(shù)組中查找數(shù)字出現(xiàn)次數(shù)問(wèn)題
本文終于介紹了分別通過(guò)Java和C++實(shí)現(xiàn)統(tǒng)計(jì)一個(gè)數(shù)字在排序數(shù)組中出現(xiàn)的次數(shù)。文中詳細(xì)介紹了實(shí)現(xiàn)思路,感興趣的小伙伴可以跟隨小編學(xué)習(xí)一下2021-12-12java WebSocket實(shí)現(xiàn)聊天消息推送功能
這篇文章主要為大家詳細(xì)介紹了java WebSocket實(shí)現(xiàn)聊天消息推送功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07linux下用renameTo方法修改java web項(xiàng)目中文件夾名稱的實(shí)例
下面小編就為大家?guī)?lái)一篇linux下用renameTo方法修改java web項(xiàng)目中文件夾名稱的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06SpringBoot中l(wèi)ogback日志保存到mongoDB的方法
這篇文章主要介紹了SpringBoot中l(wèi)ogback日志保存到mongoDB的方法,2017-11-11