Java 以「萬事萬物皆物件」為核心哲學,徹底貫徹物件導向設計。本文系統梳理 Java 物件模型的關鍵概念:參考變數、類別定義、匯入機制、static 成員、陣列安全性、作用域規則、命名空間與垃圾回收,並對比 C/C++ 差異,幫助開發者建立正確心智模型。
宣告 String s; 僅建立一個參考變數(遙控器),尚未建立實際物件(電視)。必須透過 new 在堆積配置記憶體:
String s = new String("asdf"); // 參考 s 指向新建立的 String 物件
參考變數可重新指向其他物件,原物件若無其他參考指向,將由 GC 回收。
定義類別即定義一類物件的特徵(欄位)與行為(方法):
class DateOnly {
int i;
float f;
boolean b;
}
DateOnly d = new DateOnly();
d.i = 47;
d.f = 1.1f;
d.b = false;
類別欄位 (instance field) 若為基本型別,Java 保證自動初始化(0/0.0/false/null)。但區域變數 (local variable) 不會自動初始化,編譯器強制要求賦值後才能使用,避免 C/C++ 型未初始化變數導致的未定義行為。
import java.util.ArrayList; // 單一類別
import java.util.*; // 套件下所有類別(編譯稍慢,不影響執行期)
本質上是讓原始碼使用簡短類別名稱,編譯器自動解析完整限定名稱。
static 欄位/方法屬於類別本身,不需建立實例即可存取:
class StaticTest {
static int i = 47;
static void incr() { i++; }
}
// 兩種存取方式效果相同
StaticTest st = new StaticTest();
st.incr(); // 透過實例
StaticTest.incr(); // 透過類別(推薦)
所有實例共享同一份 static 欄位記憶體。
| 特性 | C/C++ | Java |
|---|---|---|
| 陣列 | 連續記憶體區塊,無邊界檢查,易緩衝區溢位 | 第一級物件,自動初始化,執行期邊界檢查,違規拋 ArrayIndexOutOfBoundsException |
| 作用域 | 允許內層區塊遮蔽外層同名變數 {int x; {int x;}} | 禁止遮蔽,編譯錯誤,避免混淆 |
| 記憶體管理 | 手動 new/delete/malloc/free,易洩漏/重複釋放 | 垃圾回收器自動回收無參考物件,程式設計師專注業務邏輯 |
| 命名空間 | 全域函數/變數易衝突,C++ 引入 namespace 緩解 | 套件機制 (package) 對應網域名稱反寫 (com.company.project),天然全域唯一 |
GC 定期掃描堆積,判斷物件是否可達(從 GC Roots 如區域變數、static 欄位、JNI 參考等出發可達)。不可達物件標記回收,記憶體歸還堆積。開發者無法強制 GC,僅能建議 System.gc()。
常見誤區:
null 即釋放記憶體 → 僅切斷參考,實際回收由 GC 決定時機try-with-resources / Cleanercom.company.moduleUserServicegetUserName()MAX_RETRY_COUNT理解參考與物件分離、static 語意、GC 行為、套件命名空間,是寫出健壯 Java 程式的基石。拋棄 C/C++ 手動記憶體與指標思維,擁抱「物件即服務、生命週期交給容器」的現代開發範式。