Java中字符串的那些事

在Java的學(xué)習(xí)過(guò)程中,字符串的處理是絕對(duì)繞不過(guò)去的檻详恼。初學(xué)時(shí)總是被奇怪的String搞的莫名其妙,也曾經(jīng)對(duì)面試中各種String的相等搞到暈頭轉(zhuǎn)向。

在學(xué)習(xí)過(guò)JVM的機(jī)制和閱讀過(guò)JDK源碼后才算是撥開(kāi)云霧識(shí)得廬山真面目媚创。

String類

我們經(jīng)常說(shuō)String類是不可變類,說(shuō)String對(duì)象是不可變對(duì)象彤恶,具體是因?yàn)槭裁茨兀?/p>

從String的源碼來(lái)看钞钙,String類被final關(guān)鍵字修飾使得它成為不可變類。不可變類的特性使得我們不能繼承String類來(lái)實(shí)現(xiàn)新的類声离,并且String類中的方法也默認(rèn)為final方法芒炼,無(wú)法被覆寫。

String類的底層是使用了字符數(shù)組char[]來(lái)進(jìn)行存儲(chǔ)术徊,從String對(duì)象的操作處理來(lái)看焕议,每次當(dāng)我們?cè)噲D去改變String對(duì)象的時(shí)候,實(shí)際上都沒(méi)有修改到原來(lái)的對(duì)象弧关,而是產(chǎn)生并返回了一個(gè)新的對(duì)象盅安,包括使用“+”運(yùn)算符進(jìn)行操作。

image.png
image.png

String的相等

你肯定不止一次的在筆試題中遇到讓你判斷字符串是否相等的題目世囊。其實(shí)基于上述String的特性再加一點(diǎn)JVM的知識(shí)别瞭,再也沒(méi)有什么能難倒你。

需要明確的包括下面幾個(gè)關(guān)鍵點(diǎn):

  1. String對(duì)象為不可變對(duì)象株憾,對(duì)它的修改會(huì)生成一個(gè)新的對(duì)象(新的內(nèi)存區(qū)域)并返回蝙寨。

  2. 在編譯期的字面量和符號(hào)引用會(huì)被直接編譯存儲(chǔ)在class類的常量池,如:String s = “hello”嗤瞎,在運(yùn)行期隨著類的加載進(jìn)入運(yùn)行期常量池墙歪。

  3. 通過(guò)new關(guān)鍵字創(chuàng)建的對(duì)象會(huì)在堆內(nèi)存進(jìn)行分配。

  4. 字面量和字面量的“+”操作在編譯期即被優(yōu)化為最終的結(jié)果贝奇。String s = “hello” + “world”即等同于String s = “hello world”虹菲。但引用值和字面量的操作不會(huì)被優(yōu)化。

  5. final關(guān)鍵字修飾的變量會(huì)被編譯存儲(chǔ)到常量池掉瞳,在進(jìn)行“+”操作時(shí)等同于字面量毕源,會(huì)直接被優(yōu)化浪漠。

  6. String類的intern()方法會(huì)在常量池創(chuàng)建指定的值,如果已經(jīng)存在則直接返回霎褐。

舉例1

String a = “hello world”址愿,String b = “hello” + “world”; System.out.println(a == b);

結(jié)果:true

b的定義為字面量直接相加,因此會(huì)在編譯時(shí)進(jìn)行優(yōu)化冻璃,查看反編譯的類可以看到類中b的定義為String b = “hello world”响谓。

舉例2

String a = “hello world”, String b = a + “world”; final String c = “hello”, String d = c + “world”; System.out.println(a == b); System.out.println( a == d);

結(jié)果:false;true

因b的定義是通過(guò)引用和字面量相加得到省艳,所以并不會(huì)被優(yōu)化娘纷。從反編譯類可以可以看出b的定義并沒(méi)有發(fā)生變化,因此b會(huì)在運(yùn)行期創(chuàng)建和分配拍埠。而c因?yàn)橛衒inal關(guān)鍵字修飾失驶,從而d在編譯期會(huì)直接被優(yōu)化為“hello world”

舉例3

String a = “hello world”, String b = new String(“hello world”), String c = b.intern(); System.out.println(a == b); System.out.println(a == c)

結(jié)果:false, true

因a為字面常量,而b使用new來(lái)創(chuàng)建枣购,會(huì)在堆內(nèi)存進(jìn)行分配嬉探,因此a==b結(jié)果為false;

C通過(guò)String的intern()方法在常量池創(chuàng)建,而”hello world”已經(jīng)存在棉圈,所以直接返回與a相同的引用涩堤。

StringBuilder和StringBuffer

首先看下StringBuilder和StringBuffer的區(qū)別。從源碼可以很清楚看出兩個(gè)類都是繼承自同一個(gè)類分瘾,所以底層的實(shí)現(xiàn)基本相同胎围,唯一的區(qū)別在于StringBuffer是設(shè)計(jì)為線程安全的,所以提供的公共方法都增加synchroinzed關(guān)鍵字來(lái)保證同步德召。也因此在使用上StringBuffer的效率會(huì)比StringBuilder要低白魂。所以在不需要考慮線程安全的情況下,我們通常選擇StringBuilder上岗。

image.png
image.png
image.png
image.png

其次福荸,設(shè)計(jì)StringBuilder或者StringBuffer的意義何在?

從上面我們知道String對(duì)象的不可變性導(dǎo)致當(dāng)我們對(duì)String對(duì)象進(jìn)行修改時(shí)總是會(huì)創(chuàng)建一個(gè)新對(duì)象(涉及背后的一系列內(nèi)存分配操作)肴掷,因此當(dāng)需要頻繁改變String對(duì)象時(shí)敬锐,比如常見(jiàn)的循環(huán)操作對(duì)String對(duì)象進(jìn)行修改,會(huì)造成大量的內(nèi)存分配操作導(dǎo)致效率降低呆瞻。而StringBuilder或StringBuffer實(shí)現(xiàn)了對(duì)底層存儲(chǔ)數(shù)組的直接修改來(lái)提升效率台夺。

以上就是Java字符串的那些事兒,相信以后它不會(huì)再造成困擾了痴脾。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末颤介,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌买窟,老刑警劉巖丰泊,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件薯定,死亡現(xiàn)場(chǎng)離奇詭異始绍,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)话侄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門亏推,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人年堆,你說(shuō)我怎么就攤上這事吞杭。” “怎么了变丧?”我有些...
    開(kāi)封第一講書人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵芽狗,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我痒蓬,道長(zhǎng)童擎,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任攻晒,我火速辦了婚禮顾复,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鲁捏。我一直安慰自己芯砸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布给梅。 她就那樣靜靜地躺著假丧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪动羽。 梳的紋絲不亂的頭發(fā)上包帚,一...
    開(kāi)封第一講書人閱讀 51,541評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音曹质,去河邊找鬼婴噩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛羽德,可吹牛的內(nèi)容都是我干的几莽。 我是一名探鬼主播,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼宅静,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼章蚣!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤纤垂,失蹤者是張志新(化名)和其女友劉穎矾策,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體峭沦,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贾虽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了吼鱼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蓬豁。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖菇肃,靈堂內(nèi)的尸體忽然破棺而出地粪,到底是詐尸還是另有隱情,我是刑警寧澤琐谤,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布蟆技,位于F島的核電站,受9級(jí)特大地震影響斗忌,放射性物質(zhì)發(fā)生泄漏质礼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一飞蹂、第九天 我趴在偏房一處隱蔽的房頂上張望几苍。 院中可真熱鬧,春花似錦陈哑、人聲如沸妻坝。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)刽宪。三九已至,卻和暖如春界酒,著一層夾襖步出監(jiān)牢的瞬間圣拄,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工毁欣, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留庇谆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓凭疮,卻偏偏與公主長(zhǎng)得像饭耳,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子执解,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 前言 最先接觸編程的知識(shí)是在大學(xué)里面,大學(xué)里面學(xué)了一些基礎(chǔ)的知識(shí)新蟆,c語(yǔ)言觅赊,java語(yǔ)言,單片機(jī)的匯編語(yǔ)言等琼稻;大學(xué)畢...
    oceanfive閱讀 3,079評(píng)論 0 7
  • 一.你了解String類嗎欣簇? 想要了解一個(gè)類规脸,最好的辦法就是看這個(gè)類的實(shí)現(xiàn)源代碼坯约,String類的實(shí)現(xiàn)在 \jdk...
    Viking_Den閱讀 673評(píng)論 0 3
  • 本文是我自己在秋招復(fù)習(xí)時(shí)的讀書筆記熊咽,整理的知識(shí)點(diǎn),也是為了防止忘記闹丐,尊重勞動(dòng)成果横殴,轉(zhuǎn)載注明出處哦!如果你也喜歡卿拴,那...
    波波波先森閱讀 831評(píng)論 1 6
  • 集合框架: 1)特點(diǎn):存儲(chǔ)對(duì)象衫仑;長(zhǎng)度可變;存儲(chǔ)對(duì)象的類型可不同2)Collection(1)List:有序的堕花;元素...
    Demo_Yang閱讀 1,260評(píng)論 0 4
  • 本周文狱,孫碩集中去輔導(dǎo)班,學(xué)作業(yè)缘挽,預(yù)習(xí)新內(nèi)容瞄崇。舞蹈和古箏暫停。假期期間壕曼,因?yàn)閷O碩上學(xué)時(shí)間晚苏研,常拖拖拉拉耽擱。發(fā)現(xiàn)問(wèn)題...
    孫碩媽閱讀 181評(píng)論 0 1