(1)首先一點是沒有考慮對象具體存儲在什麼地方
當創建一個String str1 = "abc"的時候,編譯器會首先查看字符串池(不是堆也不是棧,比較特殊)中有沒有這個“abc”對象,如果有的話,就不再創建這個對象,而是讓這個str1引用指向這個對象,而String str2 = new String("abc");則不管有沒有這個對象都是重新創建。
例子
(2)String str = new String("abc");到底創建幾個對象的問題,及對象分配在堆中還是棧中的問題
看引用文章:http://www.blogjava.net/mirenxiaoxiao/archive/2010/10/18/335457.html
當執行String a="abc";時,JAVA虛擬機會在棧中創建三個char型的值'a'、'b'和'c',然後在堆中創建一個String對象,它的值(value)是剛纔在棧中創建的三個char型值組成的數組{'a','b','c'},最後這個新創建的String對象會被添加到字符串池中。如果我們接着執行String b=new String("abc");代碼,由於"abc"已經被創建並保存於字符串池中,因此JAVA虛擬機只會在堆中新創建一個String對象,但是它的值(value)是共享前一行代碼執行時在棧中創建的三個char型值值'a'、'b'和'c'。
(3)創建對象,內存回收問題。
創建的對象本身是在堆中開闢空間的,這個空間有個地址,於是在棧中就創建一個變量,值爲這個地址,這個變量成爲引用變量。什麼時間釋放對象呢?當沒有引用變量指向它的時候,這個堆中的對象變成垃圾,但是還佔內存,在某個不確定的時間,被垃圾回收器收走,這也是java佔內存的原因。