java中的棧

鴨脖發表於2012-04-21
我們知道java中的引用變數都是儲存在棧中的。現在假使我們宣告一個String變數,String a;這裡我們就是在建立一個String引用,那麼a其實就代表的是一個地址。編譯器在做的時候就是為該引用變數在棧中分配一塊記憶體,並且將該記憶體清零。(偶一直想獲取該塊記憶體的地址,但是java不允許程式設計師管理記憶體所以不知道該怎麼做)。當將該引用初始化的時候,如a = new String("abc");那麼這塊棧記憶體中便寫入了該String物件在堆中的地址。但是由於基本資料型別是儲存在棧中的,所以對於基本資料型別的變數的引用,棧記憶體中儲存的便是棧地址。而且由於棧有一個很重要的特殊性,就是存在棧中的資料可以共享。假設我們同時定義: 

複製內容到剪貼簿程式碼: 
int a = 3; 
int b = 3; 
編譯器先處理int a = 3;首先它會在棧中建立一個變數為a的引用,然後查詢有沒有字面值為3的地址,沒找到,就開闢一個存放3這個字面值的地址,然後將a指向3的地址。接著處理int b = 3;在建立完b的引用變數後,由於在棧中已經有3這個字面值,便將b直接指向3的地址。這樣,就出現了a與b同時均指向3的情況。

特別注意的是,這種字面值的引用與類物件的引用不同。假定兩個類物件的引用同時指向一個物件,如果一個物件引用變數修改了這個物件的內部狀態,那麼另一個物件引用變數也即刻反映出這個變化。相反,通過字面值的引用來修改其值,不會導致另一個指向此字面值的引用的值也跟著改變的情況。如上例,我們定義完a與b的值後,再令a=4;那麼,b不會等於4,還是等於3。在編譯器內部,遇到a=4;時,它就會重新搜尋棧中是否有4的字面值,如果沒有,重新開闢地址存放4的值;如果已經有了,則直接將a指向這個地址。因此a值的改變不會影響到b的值。


【注】資料型別包裝類的值不可修改。不僅僅是String類的值不可修改,所有的資料型別包裝類都不能更改其內部的值。 

相關文章