最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

知識(shí)分享!String對(duì)象的詳解

2020-12-24 11:40 作者:光耀三十洲  | 我要投稿

前言

String是Java中十分常用的類,在面試題中也是出鏡率很高的???,本文將我自己學(xué)習(xí)中遇到的一些問(wèn)題進(jìn)行整理,如果有誤,歡迎指正。

String對(duì)象判等

千萬(wàn)不要用 == 去判斷String對(duì)象是否相等,==比較的是地址。JVM只會(huì)共享字符串常量,因此,即使是“看起來(lái)”值相同的字符串,用==判斷也可能不相等。

舉例來(lái)說(shuō),下面這段代碼中,變量x和y都指向了常量池中共享的"a",地址相同,但是z是Java堆中的新建對(duì)象的引用,其地址與x不同,所以返回了false。

并且每次new一個(gè)String對(duì)象時(shí),即使字符串內(nèi)容相同,也會(huì)新開辟一片空間存儲(chǔ)對(duì)象,因此zzCopy地址也是不用的。

這部分的細(xì)節(jié)原理在下一部分中解釋。總而言之,如果你只是想判斷兩個(gè)String對(duì)象的內(nèi)容是否一樣,請(qǐng)使用x.equals(z)的形式。

代碼一

String與常量池

我們?cè)诮oString類型的引用賦值的時(shí)候會(huì)先看常量池中是否存在這個(gè)字符串對(duì)象的引用,若有就直接返回這個(gè)引用,若沒(méi)有,就在堆里創(chuàng)建這個(gè)字符串對(duì)象并在字符串常量池中記錄下這個(gè)引用。

注意:常量池中存放的是引用,并不是實(shí)例!??!

下面結(jié)合具體代碼來(lái)理解這段話,看下面這段代碼

代碼二

image-20201217221631030

可以看到,常量池中最中只保留了一份"a"的引用。因?yàn)樵?code>String z = "a";執(zhí)行時(shí),字符串常量池中已經(jīng)有"a"的引用了,不會(huì)重復(fù)創(chuàng)建。

同時(shí)我們注意到,對(duì)應(yīng)String y = "a" + "b";這條語(yǔ)句,因?yàn)?#34;a"和"b"都是編譯器就能確定的常量,所以常量池只保留了最終計(jì)算的結(jié)果,并沒(méi)有單獨(dú)保留"b"。

我們將代碼稍作修改,然后再次反編譯。

代碼三

image-20201217224254711

可以看出,最終常量池只存儲(chǔ)了"Geralt""Yennefer"兩個(gè)引用,而沒(méi)有存放拼接的結(jié)果。因?yàn)?code>witcher和sorceress變量要運(yùn)行時(shí)才能確定。但是如果將變量witchersorceress都聲明為final,那編譯期就可以確定,因此拼接結(jié)果的引用信息也會(huì)放入常量池。

總結(jié)

對(duì)于字符串表達(dá)式而言

1、對(duì)于編譯期能直接確定的值(字面量、聲明為final的變量),會(huì)直接將表達(dá)式的結(jié)果放入常量池。

2、如果編譯期不能直接直接確定(非final的變量),那么只將已經(jīng)聲明字符串字面常量放入常量池,表達(dá)式的結(jié)果不放入常量池。

另一個(gè)出鏡率很高的問(wèn)題是如下的這段代碼創(chuàng)建了幾個(gè)對(duì)象?

首先,換個(gè)問(wèn)法,這段代碼在運(yùn)行時(shí)涉及幾個(gè)String實(shí)例?

一種合理的解釋是:兩個(gè),一個(gè)是字符串字面量"xyz"所對(duì)應(yīng)的、駐留(intern)在一個(gè)全局共享的字符串常量池中的實(shí)例,另一個(gè)是通過(guò)new String(String)創(chuàng)建并初始化的、內(nèi)容與"xyz"相同的實(shí)例。

StringBuilder與StringBuffer

如果你查看過(guò)源碼,就會(huì)發(fā)現(xiàn)String對(duì)象是被final修飾的,這意味著它是不可變的。因此,當(dāng)我們拼接字符串時(shí),會(huì)產(chǎn)生新的對(duì)象。為此,設(shè)計(jì)者們提供了StringBuilder類來(lái)避免產(chǎn)生過(guò)多的中間對(duì)象。當(dāng)我們用+拼接字符串時(shí),編譯器會(huì)自動(dòng)幫我們使用StringBuilder進(jìn)行優(yōu)化。

這次使用jad對(duì)代碼二進(jìn)行反編譯(直接用javap -v也可以,但是使用jad產(chǎn)生的結(jié)果更容易看懂)

得到如下結(jié)果 可以看到編譯器自動(dòng)為我們使用了StringBuilder

有人會(huì)說(shuō),既然編譯器已經(jīng)優(yōu)化,我們就直接使用+拼接字符串就可以啊,為什么還要用StringBuilder?

來(lái)看這段代碼

代碼四

可以看出,每一輪的for循環(huán)都新建了一個(gè)StringBuilder,這是完全沒(méi)有必要的。因此,我們應(yīng)該在for循環(huán)外部先定義一個(gè)StringBuilder對(duì)象,這樣只新建了一個(gè)對(duì)象就完成了任務(wù),效率大增。

StringBufferStringBuilder基本相同,但是它保證了線程安全,如果有多線程需求,可以按需使用。

String.intern()

我們用下面這段代碼來(lái)分析intern的作用

代碼五

原來(lái),當(dāng)一個(gè)對(duì)象調(diào)用intern方法時(shí),會(huì)查看常量池是否有與當(dāng)前對(duì)象內(nèi)容相同的字面量,如果有,就直接返回常量池中的引用信息,如果沒(méi)有,就在常量池中補(bǔ)充當(dāng)前對(duì)象的字面量,然后返回引用。

總結(jié)

以上就是String類型經(jīng)常引起疑惑的一些知識(shí)點(diǎn)。總結(jié)不易,如果有幫到你,希望可以點(diǎn)個(gè)贊,謝謝~

了解更多,請(qǐng)點(diǎn)擊:https://www.bilibili.com/video/BV1L7411N77n



作者:EzioZhao
鏈接:https://juejin.cn/post/6907580432485711886
來(lái)源:掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。


知識(shí)分享!String對(duì)象的詳解的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
兴业县| 烟台市| 白朗县| 黑水县| 金昌市| 巴楚县| 老河口市| 武隆县| 宣恩县| 微博| 封开县| 城市| 凤阳县| 海阳市| 桂林市| 汨罗市| 崇义县| 定陶县| 博乐市| 基隆市| 交城县| 共和县| 建德市| 天全县| 沾益县| 九江县| 大竹县| 牡丹江市| 石台县| 龙井市| 丹棱县| 吉木乃县| 林芝县| 伊吾县| 牡丹江市| 徐汇区| 宝兴县| 广灵县| 龙州县| 普兰店市| 木兰县|