面试字节我被String类的问题给问死了!
“+” 是怎么連接字符串的?(JDK1.7及以上)
總結(jié):
使用 “+” 連接字符串時(shí),實(shí)際上是使用臨時(shí)創(chuàng)建的StringBuilder對(duì)象來輔助完成的。
對(duì)于編譯時(shí)常量,在編譯后直接計(jì)算出字符串的值,而不會(huì)在運(yùn)行時(shí)創(chuàng)建臨時(shí)的StringBuilder對(duì)象來完成字符串連接。
在循環(huán)中對(duì)String對(duì)象進(jìn)行連接,應(yīng)該直接使用StringBuilder代替 “+”,這樣可以提高性能。
注意: 當(dāng)使用運(yùn)算符 “+” 連接字符串時(shí),如果兩個(gè)操作數(shù)都是編譯時(shí)常量,則在編譯時(shí)期就會(huì)計(jì)算該字符串的值,而不會(huì)在運(yùn)行時(shí)創(chuàng)建StringBuilder對(duì)象。
不可修改的String對(duì)象
<1> 問:String對(duì)象一經(jīng)創(chuàng)建,不能修改,為什么?
因?yàn)镾tring類是final類型的,無法繼承該類。
其所有的成員變量都是private的,并且沒有提供修改私有成員變量的公有(public)方法
對(duì)String對(duì)象的操作都沒有修改當(dāng)前對(duì)象,而是新創(chuàng)建一個(gè)對(duì)象
<2> 問:把String對(duì)象設(shè)計(jì)成不可修改有什么好處嗎?
最大好處就是可以實(shí)現(xiàn)資源共享,多線程操作時(shí),具有線程安全性。
總結(jié)三點(diǎn):
- String類是final類型的,其對(duì)象一旦創(chuàng)建,不可修改。
- String類那些看似修改字符序列的方法實(shí)際上都是返回新創(chuàng)建的String對(duì)象,而不是修改自身對(duì)象。
- String對(duì)象不可改變,因此具有線程安全性,可自由實(shí)現(xiàn)共享。
String類的內(nèi)部實(shí)現(xiàn)
在String類內(nèi)部,使用一個(gè)字符數(shù)組char[]來維護(hù)字符序列。
問:String的最大長度是多少?
String的最大長度也就是字符數(shù)組char[]的最大長度,理論上為int類型的最大值,即2147483647,實(shí)際上,一般可獲取的最大值小于理論最大值。
申請(qǐng)一個(gè)int最大值長度字符數(shù)組:
char c = new char[Integer.MAX_VALUE]; // 報(bào)錯(cuò)報(bào)錯(cuò):一個(gè)char類型占用2字節(jié),Integer.MAX_VALUE個(gè)char類型接近于4GB大小,申請(qǐng)這么大一塊連續(xù)內(nèi)存空間,導(dǎo)致內(nèi)存溢出。
//加入Java開發(fā)交流君樣:756584822一起吹水聊天
分析:Java中的對(duì)象是分配在堆上的,默認(rèn)的堆空間的最大值是256MB,在理想的情況下,只要我們將最大Java堆設(shè)置的足夠大,就可以申請(qǐng)到最大的字符長度,即Integer.MAX_VALUE。
java -Xmx1G com.fan.fragmentlearning.str.StringDemoMain – 設(shè)置Main方法最大Java堆
String常量池
<1> 什么是String常量池?
String常量池是String類內(nèi)部私有的,能夠自動(dòng)將String字面常量加入其中。
起初,常量池是空的,當(dāng)程序中出現(xiàn)String字面常量時(shí),會(huì)在常量池中搜索是否存在該String對(duì)象,即使用String類的equals方法來判斷,如果不存在,就將這個(gè)字面常量加入常量池中,并返回該對(duì)象;否則直接返回常量池中的對(duì)象。
<2> String字面常量和String常量表達(dá)式都會(huì)加入常量池中。
<3> 滿足什么條件才算是String常量表達(dá)式呢?
即就是在編譯的時(shí)候就可以確定其值的String類型表達(dá)式。編譯器的原則是:能在編譯期間計(jì)算的,就不會(huì)留到運(yùn)行時(shí)再去計(jì)算。
第一種: 表達(dá)式全部由String字面常量拼接
String s = "a" + "b" + "c";第二種: 表達(dá)式由String字面常量,基本類型字面常量,final修飾的String引用,final修飾的基本數(shù)據(jù)類型任意組合組成。
String s = "a" + 5; // String常量表達(dá)式final String str = "a"; String s = "bc" + str; // String常量表達(dá)式final int num = 5; String s = "a" + num; // String常量表達(dá)式String s = str + num; // String常量表達(dá)式<4> intern方法 - 拘留字符串
如果需要將某個(gè)String對(duì)象加入常量池中,就可以調(diào)用intern方法來完成,這個(gè)操作也稱作拘留字符串。
系統(tǒng)自動(dòng)將String字面常量與String常量表達(dá)式的字符串值加入常量池中,也是通過調(diào)用intern方法來實(shí)現(xiàn)的。
要點(diǎn)總結(jié):
String類維護(hù)一塊特殊的區(qū)域,稱為常量池。因?yàn)镾tring對(duì)象是不可改變的,因此沒有必要?jiǎng)?chuàng)建兩個(gè)相同的String對(duì)象。只需將String對(duì)象加入常量池,在需要的時(shí)候取出,這樣即可實(shí)現(xiàn)String對(duì)象的共享。
在程序中出現(xiàn)String編譯時(shí)常量(String字面常量與String常量表達(dá)式),會(huì)自動(dòng)調(diào)用intern方法,如果常量池中含有相等的String對(duì)象(使用String類的equals方法來判斷),則直接返回常量池中的對(duì)象;否則將對(duì)象加入常量池中并返回該對(duì)象。
對(duì)于運(yùn)行時(shí)創(chuàng)建的String對(duì)象(非String編譯時(shí)常量),會(huì)分配到堆中,系統(tǒng)不會(huì)自動(dòng)調(diào)用intern方法拘留該對(duì)象,不過我們依然可以自行調(diào)用該對(duì)象的intern方法對(duì)該對(duì)象進(jìn)行拘留。
最后,祝大家早日學(xué)有所成,拿到滿意offer
總結(jié)
以上是生活随笔為你收集整理的面试字节我被String类的问题给问死了!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 王力宏遭多家品牌解约 主理品牌被多平台火
- 下一篇: 二面京东,面试官直接问我JVM,我心里一