Java 陣列是**固定長度、同類型元素、堆上分配**的引用類型容器。雖語法與 C/C++ 相似,但語義差異巨大。本文系統梳理三種定義方式、動態創建機制、記憶體模型與常見誤區。
int[] scores = {90, 85, 95, 100}; // 推薦:類型在變數前
int scores2[] = {90, 85, 95, 100}; // C 風格:類型在變數後 (不推薦)
int[] arr = new int[5]; // 長度 5,元素預設為 0
String[] names = new String[3]; // 長度 3,元素預設為 null
double[] vals = new double[10]; // 長度 10,元素預設為 0.0
// 作為方法參數直接傳遞
printNames(new String[]{"Alice", "Bob", "Carol"});
// 重新賦值給已宣告變數
int[] data;
data = new int[]{1, 2, 3}; // 合法
// data = {1, 2, 3}; // 編譯錯誤:非宣告語句不可用大括號初始化
Java 允許使用變數指定陣列長度,這是相對 C 語言 VLA (Variable Length Array) 的重大改進 (C99 支援 VLA 但 C11 移至可選,C++ 標準不支援):
import java.util.Scanner;
public class DynamicArrayDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("請輸入陣列長度: ");
int len = sc.nextInt(); // 運行期輸入
int[] arr = new int[len]; // 合法!長度由變數決定
arr[0] = 100;
System.out.println("首元素: " + arr[0]);
}
}
本質: `new int[len]` 在**堆上**分配連續記憶體,長度寫入陣列頭部元資料,JVM 保證記憶體安全 (邊界檢查)。
| 特性 | Java | C/C++ |
|---|---|---|
| 記憶體位置 | 堆 (Heap) | 棧 (區域變數) / 堆 (malloc) |
| 長度屬性 | `arr.length` (final 欄位) | 無 (需自行維護) |
| 邊界檢查 | JVM 自動執行,越界拋 `ArrayIndexOutOfBoundsException` | 無檢查,越界導致未定義行為 (緩衝區溢位) |
| 預設初始化 | 自動填充預設值 | 不初始化 (垃圾值),靜態/全域變數為 0 |
| 陣列名稱 | 引用變數 (指向堆物件) | 首元素地址 (指針/地址常量) |
| 多維陣列 | 陣列的陣列 (鋸齒陣列支援) | 連續記憶體塊 (固定列數) |
| 傳遞給方法 | 傳引用值 (可修改元素,不可換引用) | 退化為指針 `int*` (需額外傳長度) |
int[][] matrix = new int[3][4]; // 3 行 4 列
matrix[0][0] = 1;
// 記憶體結構:matrix → [ref→row0, ref→row1, ref→row2]
// 每 row 獨立 new int[4]
int[][] jagged = new int[3][];
jagged[0] = new int[2];
jagged[1] = new int[5];
jagged[2] = new int[3];
// 記憶體:每行獨立分配,長度任意
int[][] grid = {
{1, 2, 3},
{4, 5},
{6, 7, 8, 9}
};
int[] a = {1, 2, 3};
int[] b = a; // b 指向同一陣列物件
b[0] = 99;
System.out.println(a[0]); // 99!非預期修改
解決: 深拷貝 `int[] b = a.clone();` 或 `Arrays.copyOf(a, a.length)`
int[] arr;
System.out.println(arr[0]); // 編譯錯誤:區域變數未初始化
// 但欄位 (field) 預設為 null,存取拋 NullPointerException
int[] arr = new int[-1]; // 編譯通過,運行拋 NegativeArraySizeException
Java 陣列是**高效能、低層級、固定長度**的基礎構建塊。理解其堆分配、邊界檢查、引用語義、預設初始化等機制,是寫出正確、高效 Java 代碼的前提。動態創建能力 (`new int[n]`) 讓 Java 擺脫了 C 語言編譯期常量長度的限制,同時保證了記憶體安全。