一、到底創建了幾個對象
1、String str = “abc”; 創建了幾個對象?0個 或者 1個
2、String str = new String(“abc”);創建了幾個對象? 1個或2個
二、首先了解幾個基本的概念: 點擊瞭解 JVM的內存管理
1、String是一個特殊的包裝類數據。即可以用String str = new String(“abc”);的形式來創建,也可以用String str = “abc”;的形式來創建。
2、JVM的堆中存放對象的實例,而JVM的棧中存儲對象的引用。
3、字符串常量池:第二部分參考文章
a、字符串的分配和其它對象一樣,是需要消耗高昂的時間和空間的,而且字符串我們使用的非常多,JVM為了提高性能和減少內存的開銷,在實例化字符串的時候進行了一些優化:使用字符串常量池。每當我們創建字符串常量時,JVM會首先檢查字符串常量池,如果該字符串在常量池中,那麼就直接返回常量池中的實例引用。如果字符串不存在常量池中,就會實例化該字符串並且將其放到常量池中。由於String字符串的不可變性我們可以十分確定常量池中一定不存在兩個相同的字符串。
b、Java中的常量池,實際上分為兩種形態:靜態常量池和運行時常量池。
靜態常量池:即*.class文件中的常量池,class文件中的常量池不僅僅包含字符串(數量 )字面量,還包含類、方法的信息,佔用class文件絕大部分空間。
運行時常量池:則是jvm虛擬機在完成類裝載操作後,將class文件中的常量池載入到內存中,並保存在方法區中,我們常說的常量池,就是指方法區中的運行時常量池。
三、String對象的創建過程
a、String str = “abc”;創建過程:
1、首先在常量池中查找是否存在內容為"abc"字符串對象。
2、如果不存在則在常量池中創建"abc",並讓str引用該對象。(也就是創建1個對象的情況)
3、如果存在則直接讓str引用該對象(該對象是存在方法區的運行時常量池中的)。(也就是創建0個對象的情況)
b、String str = new String(“abc”);創建過程:
1、首先在堆中(不是常量池)創建一個指定的對象"abc",並讓str引用指向該對象。(創建第1個對象)
2、在字符串常量池中查看是否存在內容為"abc"的字符串對象。
3、若存在,則將new出來的字符串對象與字符串常量池的對象聯繫起來。(也就是創建2個對象的情況)
4、若不存在,則在字符串常量池中創建一個內容為"abc"的字符串對象,並將堆中的對象與之聯繫起來。(也就是隻創建1個對象的情況)
c、下面代碼結果為true,說明同為常量池中的一個對象:
因為String str1 = “ab” + “c”;會查找常量池中是否存在內容為"abc"的對象,如果存在則直接讓str1引用該對象,因為String str = “abc”;已經在常量池中創建了abc對象,所以str1直接引用該對象,str == str1;
d、下面代碼結果為false,說明產生了新的對象:
因為String str3 = str2 + "c"涉及到變量(不全是常量)的相加,所以會產生新的對象,其內部實現是先new一個StringBuffer,然後append(str2)再append(“c”),然後讓str3引用toString返回的對象。
相信只要你理解了上面的內容,以後在面試的過程中,不論遇到關於String創建對象的什麼情況,你都可以應對自如,上面就是關於String創建對象的內容,如果文章對你有幫助,關注吧!
我自己是一名從事了多年開發的JAVA老程序員,今年年初我花了一個月整理了一份最適合2019年學習的java學習乾貨,可以送給每一位喜歡java的小夥伴,想要獲取的可以關注我的頭條號並在後臺私信我:【交流】,即可免費獲取。
閱讀更多 程序員小皮 的文章