String str = new String("abc")會創(chuàng)建幾個對象?
String str = new String("abc")會創(chuàng)建幾個對象?
在JVM中,會單獨劃分一塊內(nèi)存給String。字符串的分配需要消耗高昂的時間和空間,且使用又比較頻繁。JVM為了提高性能和減少內(nèi)存的開銷,在實例化字符串的時候進行優(yōu)化:使用字符串常量池。每當創(chuàng)建字符串常量時,JVM會先檢查字符串常量池,如果存在,則返回引用地址;如果不存在,就會實例化該字符串并且放到常量池中。由于String字符串的不可變性,常量池中不會出現(xiàn)兩個相同的字符串。
如果在常量池中,“abc”如果存在,就直接把“abc”對象的引用地址賦給str。找不到則創(chuàng)建對象“abc”,再把地址賦給str。
Object obj = new Object();
平常都會說創(chuàng)建了obj對象,事實上obj只是一個變量,變量里保存了Object對象的引用地址。
引用類型聲明的變量是指該變量在內(nèi)存中實際存儲的一個引用地址,實體在堆中。所以說變量是可以變的,但是實體對象不能變,即str是可變的,但“abc”不可變。
那么,String為什么是不可變的?
由源碼可知:
1.String類是final修飾的;
2.String存儲內(nèi)容是char數(shù)組;
3.char數(shù)組是final修飾的。
final關(guān)鍵字
1.修飾類:則類不可被繼承,類中的成員變量可以按需求設(shè)為final,類中的方法隱式被指定為final;
2.修飾方法:不能重寫(但可被重載幾個final修飾的方法)。這里需注意:重寫的前提是子類可繼承父類此方法,若final修飾的方法同時也是private的,則子類中定義了同樣的方法名和參數(shù),則不產(chǎn)生重寫與final的沖突,也就是說該方法屬于子類,與父類沒有關(guān)系。(類的private方法,隱式的被指定為final方法)
3.修飾基本數(shù)據(jù)類型:表示該基本數(shù)據(jù)類型的值一旦被初始化后就不能被改變。
4.修飾引用類型:初始化后不能再指向其他對象(引用地址不可變),但對象的內(nèi)容可以發(fā)生改變。
5.修飾成員變量(屬性):必須要顯示初始化。(兩種初始化方式:a.申明的時候賦值;b.在其類的所有構(gòu)造器中都為其賦值。)。
String的方法都不是在原有的字符串上進行的,而是重新生成一個新的字符串對象。即原始字符串是不改變的。
結(jié)論:
String對象一旦被創(chuàng)建就是固定不變的,對于String的任何改變都不會影響到原對象,相關(guān)的任何變化性的操作都會生成新的對象。String對象每次有變化性操作(有變化的情況)的時候,都會new一個String對象。
分析:
String str = new String("abc");
首先,new一個對象在堆中,將new String("abc")的對象的引用地址賦值給變量str。先去常量池查找“abc”是否存在。若存在,直接放引用地址;若不存在,創(chuàng)建“abc”對象,并將引用地址賦給String的有參構(gòu)造里。
答案:如果常量池中存在,則只需創(chuàng)建一個對象,否則需要創(chuàng)建兩個對象。