|
關(guān)于String類的知識(shí)經(jīng)常出現(xiàn)在面試題中,在此先記錄自己的理解。
首先明白一個(gè)事,java存在一個(gè)常量池,可以用來(lái)存儲(chǔ)字符串常量。
1 創(chuàng)建的字符串變量在內(nèi)存中的區(qū)別
兩者看似都是創(chuàng)建了一個(gè)字符串對(duì)象,但在內(nèi)存中確是各有各的想法。
String str1= “abc”; 在編譯期,JVM會(huì)去常量池來(lái)查找是否存在“abc”,如果不存在,就在常量池中開(kāi)辟一個(gè)空間來(lái)存儲(chǔ)“abc”;如果存在,就不用新開(kāi)辟空間。然后在棧內(nèi)存中開(kāi)辟一個(gè)名字為str1的空間,來(lái)存儲(chǔ)“abc”在常量池中的地址值。
String str2 = new String("abc") ;在編譯階段JVM先去常量池中查找是否存在“abc”,如果過(guò)不存在,則在常量池中開(kāi)辟一個(gè)空間存儲(chǔ)“abc”。在運(yùn)行時(shí)期,通過(guò)String類的構(gòu)造器在堆內(nèi)存中new了一個(gè)空間,然后將String池中的“abc”復(fù)制一份存放到該堆空間中,在棧中開(kāi)辟名字為str2的空間,存放堆中new出來(lái)的這個(gè)String對(duì)象的地址值。
也就是說(shuō),前者在初始化的時(shí)候可能創(chuàng)建了一個(gè)對(duì)象,也可能一個(gè)對(duì)象也沒(méi)有創(chuàng)建;后者因?yàn)閚ew關(guān)鍵字,至少在內(nèi)存中創(chuàng)建了一個(gè)對(duì)象,也有可能是兩個(gè)對(duì)象。
2 String類的特性
String類 是final修飾的,不可以被繼承。
String類的底層是基于char數(shù)組的。
3 兩個(gè)方面
1)性能效率
String類被設(shè)計(jì)成不可變(immutable)類,所以它的所有對(duì)象都是不可變對(duì)象。例如:
String str = “hello";
str = str + "world“;
所以當(dāng)上文str指向了一個(gè)String對(duì)象(內(nèi)容為“hello”),然后對(duì)str進(jìn)行“+”操作,str原來(lái)指向的對(duì)象并沒(méi)有變,而是str又指向了另外一個(gè)對(duì)象(“hello world”),原來(lái)的對(duì)象還在內(nèi)存中。
由此也可以看出,頻繁的對(duì)String對(duì)象進(jìn)行修改,會(huì)造成很大的內(nèi)存開(kāi)銷。此時(shí)應(yīng)該用StringBuffer或StringBuilder來(lái)代替String。
而new String()更加不適合,因?yàn)槊恳淮蝿?chuàng)建對(duì)象都會(huì)調(diào)用構(gòu)造器在堆中產(chǎn)生新的對(duì)象,性能低下且內(nèi)存更加浪費(fèi)。
2)安全性
對(duì)象都是只讀的,所以多線程并發(fā)訪問(wèn)也不會(huì)有任何問(wèn)題。
由于不可變,用來(lái)存儲(chǔ)數(shù)據(jù)也是極為安全的。
更多關(guān)于String類的討論,其實(shí)有很多大神已經(jīng)有了很全面的總結(jié)了,在網(wǎng)上能找到很多對(duì)String類的研究,其中我找到了一篇寫的很詳細(xì)的文章,相信以后我能完全理解上面所寫的。大家有需要的也可以來(lái)看看。
Java的string類常量池及不可變性
|