前言:從簡單類型到復雜類型的跨越
Java 資料類型分為基本類型 (8 種:byte, short, int, long, float, double, char, boolean) 與引用類型。引用類型不直接存儲值,而是存儲**指向堆內存物件的引用 (地址)**。理解引用類型的本質、初始化機制、多型表達、記憶體模型,是掌握 Java 面向對象編程的關鍵。本文系統梳理引用類型三大支柱:**類、介面、陣列**,及其核心操作。
一、引用類型核心概念
1.1 引用與物件的關係
MyObject obj = new MyObject(); // obj 是引用變數,指向堆上新建的 MyObject 實例
MyObject ref = obj; // ref 指向同一物件
obj = null; // obj 不再引用該物件,ref 仍引用
// 當無任何引用指向物件時,GC 回收
- 引用類型變數:棧上儲存 (局部變數) 或堆上儲存 (實例欄位),大小固定 (32/64 位指標)。
- 物件實例:堆上儲存,包含實例欄位、物件頭 (Mark Word, Class Pointer)。
- null 引用:特殊值,表示「不指向任何物件」。所有引用類型預設值為
null。
1.2 引用類型三大分類
- 類類型:
class MyClass {} → MyClass obj = new MyClass();
- 介面類型:
interface MyInterface {} → MyInterface ref = new MyImpl();
- 陣列類型:
int[] arr = new int[10];、MyObject[] objs = new MyObject[5];
二、類類型:物件的藍圖
2.1 宣告與初始化
// 合法
MyObject obj1 = new MyObject(); // 正常實例化
MyObject obj2 = null; // 顯式 null
MyObject obj3; // 成員變數隱式 null,局部變數需顯式初始化
// 非法
MyObject obj4 = 0; // 編譯錯誤:int 不能轉為 MyObject
MyObject obj5 = new OtherClass(); // 編譯錯誤:類型不匹配 (除非 OtherClass 繼承 MyObject)
2.2 多型與向上/向下轉型
class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
Animal a = new Dog(); // 向上轉型 (隱式) - 安全
Dog d = (Dog) a; // 向下轉型 (顯式強轉) - 需運行時檢查,可能拋 ClassCastException
// 安全向下轉型模式
if (a instanceof Dog) {
Dog d2 = (Dog) a; // Java 16+ 模式匹配: if (a instanceof Dog d2) { ... }
}
2.3 物件創建完整流程
- 類載入/驗證/準備/解析/初始化 (若未載入)。
- 堆分配記憶體 (TLAB/指針碰撞/空閒列表)。
- 記憶體歸零 (預設值)。
- 設置物件頭 (哈希碼、GC 年齡、鎖狀態、類指針)。
- 執行
<init> (建構子) 初始化邏輯。
- 返回引用地址給變數。
三、介面類型:契約的抽象
3.1 介面特性
- 定義**方法簽名契約** (Java 8+ 可有
default/static/private 方法)。
- 不能實例化:
new MyInterface() 編譯錯誤 (匿名類除外)。
- 類可
implements 多個介面 (多實現)。
- 介面可
extends 多個介面 (多繼承)。
3.2 介面引用用法
interface Comparable { void compare(Comparable other); }
class SortItem implements Comparable {
public void compare(Comparable other) { /* 實現邏輯 */ }
}
// 介面類型引用指向實現類實例
Comparable c = new SortItem(); // 合法
c.compare(new SortItem()); // 多態調用
// Comparable c2 = new Comparable(); // 錯誤:介面不能實例化
3.3 介面隔離與依賴倒置
- 高層模組依賴介面 (抽象),不依賴具體實現。
- 介面設計遵循 **ISP (介面隔離原則)**:細粒度介面優於單一臃腫介面。
四、陣列類型:特殊的引用類型
4.1 陣列本質
- 陣列**是物件**,繼承自
Object,實現 Cloneable, Serializable。
- 擁有
length 最終欄位 (非方法)。
- 元素類型可為基本類型或引用類型。
- 陣列协變性:
Dog[] → Animal[] 合法 (但寫入需類型檢查,ArrayStoreException)。
4.2 陣列操作核心 API
| 操作 | 方法/語法 | 說明 |
| 創建 | new int[10], new String[]{"a","b"} | 長度不可變 |
| 存取 | arr[i] | 邊界檢查 ArrayIndexOutOfBoundsException |
| 複製 | Arrays.copyOf(arr, newLen), System.arraycopy | 淺複製 |
| 排序 | Arrays.sort(arr), Arrays.parallelSort(arr) | 雙軸快排/併行合併排序 |
| 查找 | Arrays.binarySearch(arr, key) | 前提:已排序 |
| 轉列表 | Arrays.asList(arr) (引用類型陣列) | 返回固定大小 List 視圖 |
| 流式處理 | Arrays.stream(arr) | Java 8+ Stream API |
4.3 多維陣列
int[][] matrix = new int[3][4]; // 3 行 4 列,每行陣列獨立分配
int[][] jagged = {{1,2}, {3,4,5}, {6}}; // 齒狀陣列
五、引用類型默認值與初始化最佳實踐
| 位置 | 默認值 | 是否需顯式初始化 |
| 成員變數 (實例/靜態) | null | 否 (JVM 保證歸零) |
| 局部變數 (方法內) | 無 (編譯錯誤) | **是** (必須賦值後才能使用) |
| 陣列元素 | 基本類型 0/false, 引用類型 null | 否 (new 陣列時自動初始化) |
六、記憶體模型圖解:引用與物件
棧 (執行緒私有) 堆 (共享)
┌─────────────────────┐ ┌──────────────────────────┐
│ main() 幀 │ │ MyObject 實例 #1 │
│ ────────────────── │ │ ├ header (Mark, Class*) │
│ MyObject obj ──────┼─────────►│ ├ field1: 10 │
│ MyObject ref ──────┼──┐ │ ├ field2: "hello" │
│ │ │ │ └ field3: [ref to #2] │
│ │ │ └──────────────────────────┘
│ │ │ ▲
│ │ └────────────────┘ (ref 指向同一物件)
└─────────────────────┘
七、常見陷阱與避坑指南
- 空指針異常 (NPE):對
null 引用解引用。對策:Objects.requireNonNull、Optional、註解 @NonNull、防禦性檢查。
- 淺複製陷阱:陣列/集合複製僅複製引用。對策:深拷貝 (
clone() 實現、複製建構子、序列化、Stream map 創建新物件)。
- 陣列協變寫入失敗:
Animal[] arr = new Dog[1]; arr[0] = new Cat(); → ArrayStoreException。對策:使用泛型 List (不協變) 或檢查類型。
- 介面引用調用默認方法歧義:實現多個介面有同名默認方法。對策:類中顯式重寫並指定
InterfaceA.super.defaultMethod()。
- 最終引用誤解:
final List list = new ArrayList(); list.add(1); 合法 (引用不變,物件可變)。
結語
Java 引用類型 (類、介面、陣列) 構成了面向對象編程的骨架。**引用是操控堆上物件的句柄**,理解其初始化規則、多型表達、記憶體模型、協變性、默認值差異,是編寫正確、高效、可維護 Java 代碼的基石。現代開發中,配合**泛型擦除機制、模式匹配 instanceof、Record 類、Sealed 介面、Value Types (Valhalla 專案)** 等新特性,引用類型系統持續演進,但核心語義 —— **引用指向物件、物件封裝狀態與行為、介面定義契約** —— 永遠不變。
- 上一篇文章: 裝飾模式在 Java 中的三種實作策略:繼承、封裝與外掛
- 下一篇文章: Java 集合框架核心介面詳解:Set、SortedSet、Map 與排序機制
Copyright ©
程式碼之家 All Rights Reserved