當我們聲明一個函數內的類,並且還創建該類的一個變量,是該類的對象壓入堆棧或堆?在使用內部類的上下文中使用最終關鍵字時,我有一些困惑嗎?如果變量和類對象都存在於堆棧中,那我們爲什麼需要命名變量final?方法本地類?
親切的問候。
當我們聲明一個函數內的類,並且還創建該類的一個變量,是該類的對象壓入堆棧或堆?在使用內部類的上下文中使用最終關鍵字時,我有一些困惑嗎?如果變量和類對象都存在於堆棧中,那我們爲什麼需要命名變量final?方法本地類?
親切的問候。
當我們在函數內部聲明一個類並且還創建了該類的一個變量時,該類的對象是否被壓入棧或堆?
你的術語是不正確的,這可能是你的困惑的根源:
類的聲明不會導致任何空間來分配......除了一次性撥款用於表示類加載和初始化時發生的代碼,靜態等的空間。
Java有方法,而不是功能。
在聲明的方法(即,一個局部變量)內的變量,該變量本身的空間被分配在棧上。 (如果聲明靜態或實例變量,則該空間將成爲堆節點的一部分。)
當您創建類的實例(即對象)時,該實例的空間將分配到堆。該實例的參考可以被分配給一個先前分配變量...在棧上(用於在方法的局部變量)或堆(爲一個靜態或實例變量)...但它也可以被立即丟棄。無論哪種方式,引用的空間分配都與創建實例無關。
我有關於使用final關鍵字的一些混亂情況下與內部類使用時?如果變量和類對象都存在於堆棧中,那我們爲什麼需要命名變量final?
final
是必需的,因爲Java不支持正確的關閉。當一個內部類指的是在一個封閉的範圍本地變量會發生什麼情況是,該變量的值被傳遞到內類和存儲在隱藏變量。 final
允許編譯器有效地將其從應用程序中隱藏起來。由於應用程序無法更改變量的內容,因此無法分辨變量的兩個副本。
1 - 這是一個輕微的過度簡單化。如果您有興趣,請閱讀「逃生分析」。
2 - 這是局部變量存儲在堆棧上的規則的例外。在這種情況下,變量的副本是也存儲在內部類實例的堆節點中。然而,這是一個實現細節......就像所有堆棧與堆的東西一樣。如果JVM架構改爲支持閉包,事情可能會有所不同。
我不明白你所說的「當你創建一個類的實例(即對象)的意思,該實例的空間分配上heap1。該實例的引用可以被分配給以前分配的變量。 ..堆棧(用於在方法的局部變量)或堆上(爲一個靜態或實例變量)」 – AndroidDev
我使用標準的Java術語和簡單的英語。如果你不明白,你需要給我講什麼* *你不明白一些線索。 –
1)問每個問題一個問題,或者至少提出相關問題。 2)你嘗試使用Google搜索嗎?或閱讀文檔? – Antimony
存儲在Java堆棧上的唯一的東西是原語和引用。對象始終存儲在堆上。 – Jeffrey