Java成員變量、局部變量
分類
成員變量在使用對象之前就加載好,而局部變量需要在類或對象調用方法時纔會創建。
個人認爲,這種分類方式有點粗糙,以下是比較詳細的變量分類方式:
成員變量
在這裏,成員變量分爲類變量和實例變量。
類變量是類加載過程中的準備階段就已經分配內存了,直至類被銷燬,類變量的內存纔會釋放。
而實例變量是在類的實例創建(創建對象)時存在直至實例被銷燬。
1 訪問類變量的方式有兩種:類.類變量、實例.類變量。除了類本身可以對類變量進行修改外,類的實例也會對類變量進行修改,且其他實例也會看到變化。
2 訪問實例變量的方式就只有一種:實例.實例變量。每個實例的實例變量都不對其他實例可見。
局部變量
局部變量在此分爲形參、方法局部變量和代碼塊局部變量。
1 形參是方法簽名上的局部變量,當對象調用方法時傳入了實參,但是傳入方法的過程中會創建一個形參,作爲值傳遞的副本。
2 方法局部變量是在方法中創建變量。
3 而代碼塊局部變量,即類中定義好的代碼塊。
六個變量的加載順序如下
通過上述對變量的介紹,可以得到答案。先看主函數有沒有創建對象,有創建對象的話看對應類中代碼塊有沒有輸出語句,然後返回主函數,依次執行語句和訪問方法。可以看出,這六個變量的加載順序如下
但是這六種變量爲什麼是這樣的加載順序?
按虛擬機加載順序劃分變量類型
我們用類加載->創建對象->調用方法的順序來介紹變量的加載順序。
創建對象
而實例變量和實例代碼塊是在創建對象後,進行對象初始化的時候才加載到內存中。
調用方法
在調用有參函數的時候,虛擬機會將實參複製後,生成形參,實參和形參的值相同,但是內存地址不同,即形參相對於實參來說,只是另一個有着同樣的值的變量。
所以在有參函數調用的過程中,形參先於方法局部變量被加載。
創建位置
方法區:類信息、類變量(靜態變量和常量)、方法
堆:對象、成員變量
棧:局部變量
(1)當程序運行時,首先通過類裝載器加載字節碼文件,經過解析後裝入方法區!在方法區中存了類的各種信息,包括類變量、常量及方法。對於同一個方法的調用,同一個類的不同實例調用的都是存在方法區的同一個方法。類變量的生命週期從程序開始運行時創建,到程序終止運行時結束!
(2)當程序中new一個對象時,這個對象存在堆中,對象的變量存在棧中,指向堆中的引用!對象的成員變量都存在堆中,當對象被回收時,對象的成員變量隨之消失!
(3)當方法調用時,JVM會在棧中分配一個棧楨,存儲方法的局部變量。當方法調用結束時,局部變量消失!