Java 自動管理堆疊與堆,程式設計師無法直接控制,但理解其運作機制對寫出高效能、無 Bug 程式碼至關重要。本文從資料型別分佈、共享機制、String 特殊行為、包裝類別不可變性四大面向深入剖析。
| 特性 | Stack (堆疊) | Heap (堆) |
|---|---|---|
| 存取速度 | 極快(僅次於暫存器) | 較慢(動態配置) |
| 大小/壽命 | 編譯期確定 | 執行期動態決定 |
| 靈活度 | 低 | 高 |
| 管理方式 | 自動釋放(離開區塊) | GC 自動回收 |
| 資料共享 | 支援常量共享 | 物件預設不共享 |
int, short, long, byte, float, double, boolean, char — 無 String。以 int a = 3 形式定義,稱「自動變數」,儲存字面值而非物件參考。大小壽命已知 → 存 Stack。Integer, String, Double 等 — 以 new() 動態建立物件 → 存 Heap。int a = 3;
int b = 3;
// 編譯器:建立 a 參考 → 找不到 3 → 開闢位址存 3 → a 指向 3
// 處理 b:建立 b 參考 → 找到 3 → b 直接指向同一 3 位址
// 結果:a、b 共享同一字面值 3
關鍵差異:修改 a = 4 時,JVM 重新尋找/建立 4 位址,a 指向新位址,b 仍指向 3,**不會**像物件參考修改內部狀態那樣影響其他參考。
String 可用 new String("abc") (Heap) 或 String s = "abc" (Stack 常量池) 建立。
String s 參考變數s 指向物件 o關鍵:此模式下 String 物件的 value 欄位儲存的是指向 Stack 常量池的參考,而非直接存字元陣列。
| 程式碼 | == 結果 | equals() | 說明 |
|---|---|---|---|
| true | true | 同一物件 (常量池共享) | |
| false | false | s1 指向新物件,s2 不變 | |
| true (s1==s4) | true | s3 共享 s1 物件;s4 共享常量池 "bcd" 物件 | |
| false | true | new 強制建 Heap 物件,不共享常量池 |
所有包裝類別 (String, Integer, Double...) 內部值不可修改。修改變數值實為:JVM 建立新物件 → 變數指向新物件。頻繁修改字串請用 StringBuffer/StringBuilder。
String s="abc" 只確定建立參考,物件視上下文可能共用。除非用 new() 強制新建。s="abc" 讓 JVM 決定是否新建,符合享元模式,效能優於 new String("abc")。