1. String str = “abcdefg”;內存存儲情況
最終結論:
變量str作爲引用時放在棧中的
“abcdefg”會在堆中生成一個String對象(論證在下方)
變量 str引用這個堆中的String對象
分析論證:
測試代碼:
package com.albert.test;
public classMain {
static String s_str = null;
static String s_str1= null;
public static void main(String[] args) {
// TODO Auto-generated method stub
Mainmain1= newMain();
main1.test();
System.out.println(s_str.length());
System.out.println(s_str == s_str1);// 返回值爲TRUE,證明運行期,沒有在生成多餘的String對象
}
public void test(){
StringlocalStr= "abcdefg";
s_str = localStr;
s_str1 = localStr;
}
}
//輸出結果長度爲:7
分析:在test()函數中,localStr本身是一個引用,指向一個字符串常量。而s_str靜態變量,獲取到localStr的引用,兩個變量指向同一個字符串“abcdefg”。
那常量“abcdefg”到底是不是要生成一個String對象呢?
假設localStr,s_str所引用的是常量字符串”abcdefg”,而非含有該字符串值的字符串對象。那麼在輸出語句哪裏會報錯,因爲常量沒有方法。但是程序正確的調用函數,返回字符串的長度,而java是全部面向對象的,所以 s_str引用的是一個對象,而非字符串常量,因爲在test()中,s_str==localStr,所以localStr所引用也是對象,並且該對象包含的字符串值是”abcdefg”.
綜合上述分析”abcdefg”,在某個時刻生成了一個String對象,那對象存放在哪裏呢?如果說生成的對象放在棧中,那麼當test()執行完後,該變量會被銷燬,但是實際運行結果否定了這個假設,正確的調用了這個對象的方法。我發現,雖然是在局部函數中生成的對象,但在test()函數外,依然可以訪問,這說明假設再次失敗,該對象不是存在棧中,那究竟存在哪裏呢?排除法,棧排除,靜態池排除,剩下堆了,放在堆中,堆中對象特點:在沒有引用時對象會被清理掉,程序中直到main()函數結束才釋放對象。