Java?String相加底層原理分析
Java String相加底層原理
代碼
?? ??? ?String a = "a"; ? ? ? ? String b = "b"; ? ? ? ? String c = "c"; ? ? ? ? String s1 ?= "a"+"b"+"c"; ? ? ? ? String s2 = a+b+c; ? ? ? ? System.out.println(s2==s1); ? ? ? ? System.out.println(System.identityHashCode(s1)); ? ? ? ? System.out.println(System.identityHashCode(s2));
粗略解釋
首先了解字符串常量池,創(chuàng)建字符串對象分別有兩種,一種是字面值創(chuàng)建,一種是 new 創(chuàng)建,這兩者存儲(chǔ)的內(nèi)存地址是不一樣的。
如果是字面值創(chuàng)建的方式,如 String a="a",JVM會(huì)先去字符串常量池中尋找有沒有“a”這個(gè)字符串,若有,則將其地址給 a;若沒有,則先在常量池里創(chuàng)建“a”,然后再把地址給a;而通過 new a = new String("a")的方式創(chuàng)建對象,則是在堆中創(chuàng)建“a”對象,a 指向這個(gè)對象。
當(dāng)字符串進(jìn)行拼接時(shí),如果是字面值進(jìn)行拼接,在編譯階段會(huì)進(jìn)行優(yōu)化,直接變成字符串”abc“。
當(dāng)字符串變量相加時(shí),因被final修飾,字符串不能修改,會(huì) 先生成StringBuilder對象,通過append()方法進(jìn)行字符串拼接,在調(diào)用toString()方法形成新的字符串,所以s1可以理解為
? ? ? ? StringBuilder stringBuilder = new StringBuilder(); ? ? ? ? stringBuilder.append("a"); ? ? ? ? stringBuilder.append("b"); ? ? ? ? stringBuilder.append("c"); ? ? ? ? String s = stringBuilder.toString();
上好的String 相加
//底層底層底層底層底層底層底層底層底層底層底層底層底層底層 //底層底層底層底層底層底層底層底層底層底層底層底層底層底層 //底層底層底層底層底層底層底層底層底層底層底層底層底層底層 //底層底層底層底層底層底層底層底層底層底層底層底層底層底層 //底層底層底層底層底層底層底層底層底層底層底層底層底層底層 //底層底層底層底層底層底層底層底層底層底層底層底層底層底層 //底層底層底層底層底層底層底層底層底層底層底層底層底層底層 //底層底層底層底層底層底層底層底層底層底層底層底層底層底層 return new String(result, 0, len + resultOffset);
兩個(gè)String 對象相加,底層先生成一個(gè)StringBulider 對象,然后對兩個(gè)字符串進(jìn)行append,最后調(diào)用StringBuilder的toString方法進(jìn)行返回 新的String對象 return new String()
String a="a"; String b="b"; String c=a+b; String d=new String("ab"); System.out.println(a+b==c); //false System.out.println((a+b).equals(c)); //ture
調(diào)用equals方法時(shí)候,String重寫了equals ,比較的是String的值, 而==比較的是引用的地址的值,所以只要a+b一次就會(huì)返回一個(gè)新的String對象
看一個(gè)新的方法類似
public static boolean isAdmin(String userId){ return userId.toLowerCase()=="admin"; } public static void main(String[] args){ System.out.println(isAdmin("Admin")); }
以上代碼返回false 還是一樣底層上面方法返回 new String()
注意注意注意
String test="javaandpython"; String str1="java"; String str2="and"; String str3="python"; System. out. println(test=="java"+"and"+"python"); System. out. println(test ==str1 + str2 + str3);
第一個(gè)true 第二個(gè)false就不講了,第一個(gè)由于是字符串字面量進(jìn)行+操作,編譯階段直接有一個(gè) javaandpython的字符串再常量池中,而不是通過StringBuilder.
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java?SE循環(huán)一些基本練習(xí)題總結(jié)
循環(huán)語句可以在滿足循環(huán)條件的情況下,反復(fù)執(zhí)行某一段代碼,這段被重復(fù)執(zhí)行的代碼被稱為循環(huán)體語句,下面這篇文章主要給大家總結(jié)介紹了關(guān)于Java?SE循環(huán)一些基本練習(xí)題,需要的朋友可以參考下2024-03-03深入理解Java中的構(gòu)造函數(shù)引用和方法引用
java構(gòu)造函數(shù),也叫構(gòu)造方法,是java中一種特殊的函數(shù)。函數(shù)名與相同,無返回值。方法引用是用來直接訪問類或者實(shí)例的已經(jīng)存在的方法或者構(gòu)造方法。下面我們來詳細(xì)了解一下它們吧2019-06-06如何解決SpringBoot2.x版本對Velocity模板不支持的方案
這篇文章主要介紹了如何解決SpringBoot2.x版本對Velocity模板不支持的方案,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-12-12JAVA入門教學(xué)之快速搭建基本的springboot(從spring boot到spring cloud)
本文主要入門者介紹怎么搭建一個(gè)基礎(chǔ)的springboot環(huán)境,本文通過圖文并茂的形式給大家介紹從spring boot到spring cloud的完美搭建過程,適用java入門教學(xué),需要的朋友可以參考下2021-02-02java核心編程之文件過濾類FileFilter和FilenameFilter
這篇文章主要為大家詳細(xì)介紹了java文件過濾類FileFilter和FilenameFilter,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08SpringBoot項(xiàng)目中使用騰訊云發(fā)送短信的實(shí)現(xiàn)
本文主要介紹了SpringBoot項(xiàng)目中使用騰訊云發(fā)送短信的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04