靜態變數與方法在編譯完成後即存在 global 區 (靜態區), stack 區存放一般方法, 以及執行時期方法所用到之參數與區域變數; 而 heap 區則存放執行時期的實體物件與實體變數.
Java 的變數依照其存活時間長短分成下列四種 :
1. 類別變數 :
又稱為靜態變數, 因為它必須在類別成員區宣告為 static (也只能在類別成員區有 static), 例如 :
static int count=0;
其特性如下 :
- 存活時間最長, 編譯時即配置記憶體存放於 global 區 (即靜態區, 靜態方法也在此區), 程式執行期間均可存取.
- 直接用類別名稱存取, 即 : 類別名稱.變數名稱, 且為該類別全部實體所共用 (即共同變數).
- 可以加存取修飾子 : public, protected, private.
- 有預設值, 如果沒有初始化, 編譯器也會給予預設值如下 :
2. 實體變數 :
又稱為物件變數, 或物件的屬性, 係類別成員中沒有 static宣告之變數. 其特性如下 :
- 存活時間第二長, 於物件建立時產生, 存放於 heap 區, 只要物件未消滅皆可存取.
- 必須以物件實體名稱存取, 即 : 物件名稱.變數名稱, 同類別之不同實體有各自屬性 (不共用).
- 可以加存取修飾子 : public, protected, private.
- 有預設值, 如果沒有初始化, 編譯器也會給予預設值, 與類別變數相同.
此為方法中的小括弧 (參數) 以及大括弧 (內容) 中所用到的變數, 是兩種區域變數之一 (另一種為區塊變數). 其特性如下 :
- 存活期間最短, 僅在該方法被呼叫時存在, 配置於 statck 區 (LIFO), 方法執行完畢即消滅, 還給作業系統.
- 只能在方法內部直接存取, 故不可以加任何存取修飾子 (即外部無法存取).
- 無預設值, 存取前必須先初始化 (賦值), 否則會編譯失敗. 方法之參數因為是外部傳入 Literal (相當於初始化), 因此可以直接使用.
4. 區塊變數 :
即 if, switch, for, while, do-while 等流程控制語法大括弧內所定義之變數, 是兩種區域變數之一, 其特性如下 :
- 存活期間最短, 僅在進入該區塊執行時才存在, 配置於 statck 區 (FILO), 離開該區塊時即消滅, 還給作業系統.
- 只能在區塊內部存取, 故不可以加任何存取修飾子 (區塊外部無法存取).
- 無預設值, 存取前必須先初始化 (賦值), 否則會編譯失敗.
總之, 區域變數 (方法變數, 區塊變數) 是放在 stack 區, 執行時期動態生滅; 靜態變數放在 global 區, 編譯成功時即存在, 程式結束時消滅; 實體變數放在 heap 區, 隨實體存亡而生滅.
Stack 區應該是 LIFO 喔,您應該是筆誤了。
回覆刪除感謝您, 我已更正了.
回覆刪除請問區塊變數的部份,除了流程控制語法大括弧內所定義之變數之外,如果是{}內所產生的變數,也是屬於區塊變數嗎?
回覆刪除嗨, 是的, 在 Java 9 之後, 除了分支與迴圈的大括號外, 單純的 {} 內之變數也是區域變數.
回覆刪除