更新時(shí)間:2020-08-06 15:54:16 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽2871次
在Java面試中,字符串相關(guān)的知識(shí)是面試者比較青睞的,特別是在不同的情況下到底創(chuàng)建了幾個(gè)對(duì)象,很多人理解的并不透徹,例如String str=new String("abc")為什么會(huì)創(chuàng)建兩個(gè)對(duì)象,很多人只是知道,但是不知道為什么,接下來(lái)我已一個(gè)全面的例子作為開(kāi)場(chǎng),透徹的介紹String。

掌握下面的幾點(diǎn),所有的字符串面試題就不在是什么問(wèn)題了:
注:本文以JDK8說(shuō)明,至于JVM在每個(gè)版本的變化會(huì)在JVM面試庫(kù)中詳細(xì)介紹,在這就不展開(kāi)了。
第一點(diǎn):字符串創(chuàng)建有兩種方式:字面量和利用new關(guān)鍵字
//1:字面量創(chuàng)建字符串對(duì)象
String?str1?=?"abc";
//2:利用new關(guān)鍵字創(chuàng)建字符串對(duì)象
String?str2?=?new?String("abc");
第二點(diǎn):字符串使用非常的頻繁,從空間和性能方面考慮,JVM實(shí)例化字符串時(shí)進(jìn)行了優(yōu)化:添加了字符串常量池。
第三點(diǎn):字符串常量池中的內(nèi)容是類加載完成以后創(chuàng)建的,而字符串常量池保存的是字符串對(duì)象的引用,具體實(shí)例對(duì)象存放在堆中。
第四點(diǎn):如果只是字面量進(jìn)行拼接,JVM會(huì)將它們優(yōu)化成一個(gè)字面量。
String?str?=?"a"+"b";
//JVM會(huì)對(duì)上面的拼接進(jìn)行優(yōu)化,優(yōu)化后
String?str?=?"ab";
第五點(diǎn):如果拼接中存在字符串變量,JVM會(huì)將它們優(yōu)化成StringBuilder進(jìn)行拼接,然后通過(guò)StringBuilder.toString()獲取。
String?str1?=?"ab";
String?str2?=?str1+"c";
//上面字符串拼接存在字符串變量str1,JVM會(huì)對(duì)其優(yōu)化
String?str1?=?"ab";
StringBuilder?sb?=?new?StringBuilder();
sb.append(str1).append("c");
String?str2?=?sb.toString();
第六點(diǎn):new關(guān)鍵字會(huì)在堆上創(chuàng)建一個(gè)新的對(duì)象。
第七點(diǎn):intern()方法:返回常量池該字符串的引用
intern的作用:
1:如果字符串常量池中存在字符串對(duì)象的引用,則直接返回這個(gè)對(duì)象的引用
2:如果字符串常量池中不存在字符串對(duì)象的引用,則首先在堆中創(chuàng)建對(duì)象,然后將這個(gè)對(duì)象的引用存放在常量池中。
上面的這七點(diǎn)如果真正掌握了,我相信下面的面試就很容易了。
面試1:下面的一句代碼創(chuàng)建了幾個(gè)對(duì)象
String?str?=?new?String("abc");
答案:創(chuàng)建了兩個(gè)對(duì)象。
解析:此題主要考察了第三點(diǎn)和第六點(diǎn)。
1)創(chuàng)建的第一個(gè)對(duì)象(第三點(diǎn)):在類加載時(shí),首先判斷字符串常量中是否存在"abc"對(duì)象的引用,沒(méi)有則創(chuàng)建一個(gè)"abc"對(duì)象,然后把這個(gè)對(duì)象的引用存放在字符串常量池中。
2)創(chuàng)建的第二個(gè)對(duì)象(第六點(diǎn)):new關(guān)鍵字會(huì)在堆中創(chuàng)建一個(gè)新的對(duì)象。
面試2:下面的代碼會(huì)輸出什么
String?str1?=?"abc";
String?str2?=?"a"+"b"+"c";
String?str3?=?new?String("abc");
System.out.println(str1==str2);
System.out.println(str1==str3);
答案:true,false
解析:此題主要考察了第三點(diǎn),第四點(diǎn)和第六點(diǎn)
1)true:str2在編譯期JVM會(huì)優(yōu)化成"abc",然后判斷字符串常量池中是否存在"abc"對(duì)象的引用,因?yàn)閟tr1已經(jīng)創(chuàng)建,所以str2從字符串常量池中獲取"abc"對(duì)象的引用。所以str1和str2都是指向同一地址的引用。
2)false:上面我們知道str1指向的時(shí)字符串常量池中"abc"的引用,而str3指向的時(shí)new String()創(chuàng)建的新對(duì)象的引用,所以str1和str3指向的不是同一個(gè)地址的引用。
面試3:下面的代碼會(huì)輸出什么
String?str1?=?"abc";
String?str2?=?"ab";
String?str3?=?str2+"c";
System.out.println(str1==str3);
答案:false
解析:此題主要考察第三點(diǎn)和第五點(diǎn)
1)str1指向的時(shí)字符串常量池中"abc"對(duì)象的引用。
2)str3在編譯時(shí),JVM會(huì)將str3優(yōu)化成如下代碼。
StringBuilder?sb?=?new?StringBuilder();
sb.append(str2).append("c");
String?str3?=?sb.toString();
從上面代碼中可以看出str3指向的時(shí)對(duì)象StringBuilder()對(duì)象的引用,所以str1和str3指向不同對(duì)象,所以false.
面試4:下面代碼會(huì)輸出什么
String?str1?=?"abc";
String?str2?=?"ab";
String?str3?=?(str2+"c").intern();
System.out.println(str1==str3);
答案:true
解析:考察第三點(diǎn)和第七點(diǎn)
1)如果字符串調(diào)用intern()方法,它會(huì)查看字符串常量池中是否存在"abc"的引用,存在直接返回它的引用。所以str1和str3指向同一個(gè)對(duì)象的地址。
面試5:為什么不要在循環(huán)中去拼接字符串
答案:因?yàn)樽址唇釉诰幾g時(shí)期JVM會(huì)將其優(yōu)化成StringBuilder對(duì)象進(jìn)行拼接,如果循環(huán)次數(shù)非常大的話,創(chuàng)建的StringBuilder對(duì)象非常的多,甚至可能會(huì)導(dǎo)致內(nèi)存溢出的情況。

以上就是動(dòng)力節(jié)點(diǎn)java培訓(xùn)機(jī)構(gòu)的小編針對(duì)“Java字符串面試題深度分析”的內(nèi)容進(jìn)行的回答,希望對(duì)大家有所幫助,如有疑問(wèn),請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。
相關(guān)閱讀
Java實(shí)驗(yàn)班
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
Java就業(yè)班
有基礎(chǔ) 直達(dá)就業(yè)
Java夜校直播班
業(yè)余時(shí)間 高薪轉(zhuǎn)行
Java在職加薪班
工作1~3年,加薪神器
Java架構(gòu)師班
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)