首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 陣列定義完整指南:三種宣告方式、動態創建、與 C 語言差異對比

     編輯:Java 相關知識

Java 陣列是**固定長度、同類型元素、堆上分配**的引用類型容器。雖語法與 C/C++ 相似,但語義差異巨大。本文系統梳理三種定義方式、動態創建機制、記憶體模型與常見誤區。

三種陣列定義語法

1. 靜態初始化 (大括號列舉)


int[] scores = {90, 85, 95, 100};  // 推薦:類型在變數前
int scores2[] = {90, 85, 95, 100}; // C 風格:類型在變數後 (不推薦)
  • 編譯器自動推導長度 (此例 length=4)
  • 元素順序固定,編譯期確定
  • **只能在宣告語句中使用**,不能分離宣告與賦值

2. 動態初始化 `new type[length]` (最常用)


int[] arr = new int[5];       // 長度 5,元素預設為 0
String[] names = new String[3]; // 長度 3,元素預設為 null
double[] vals = new double[10]; // 長度 10,元素預設為 0.0
  • 長度可為變數 (運行期決定)
  • 自動按類型填充預設值 (數值 0、布爾 false、引用 null)
  • **首選方式**,靈活適用於所有場景

3. 匿名陣列 `new type[]{...}` (方法參數、臨時陣列)


// 作為方法參數直接傳遞
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 vs C/C++ 陣列核心差異對比

特性JavaC/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}
};

常見陷阱與最佳實踐

陷阱 1:引用共享 (淺拷貝)


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)`

陷阱 2:未初始化就存取


int[] arr;
System.out.println(arr[0]); // 編譯錯誤:區域變數未初始化
// 但欄位 (field) 預設為 null,存取拋 NullPointerException

陷阱 3:負數長度


int[] arr = new int[-1]; // 編譯通過,運行拋 NegativeArraySizeException

最佳實踐清單

  1. 優先使用 `int[] arr` 宣告風格 (類型在前)
  2. 動態長度用 `new int[n]`,靜態已知用 `{...}`
  3. 遍歷用 `for (int x : arr)` 增強 for 迴圈 (不可修改元素)
  4. 需修改元素用傳統 `for (int i=0; i
  5. 拷貝用 `Arrays.copyOf` / `System.arraycopy` (原生、最快)
  6. 排序用 `Arrays.sort` (雙軸快排/歸併排序混合)
  7. 大量數值計算考慮**基本類型陣列**而非 `List` (記憶體緊湊、無裝箱開銷)

現代替代:List / Stream / 專用庫

  • 動態增刪:`ArrayList` / `IntArrayList` (Eclipse Collections)
  • 函數式處理:`IntStream.of(arr).filter(...).map(...).toArray()`
  • 高效能數值計算:`double[]` + `jblas` / `ND4J` / `Vector API` (JDK 19+)

Java 陣列是**高效能、低層級、固定長度**的基礎構建塊。理解其堆分配、邊界檢查、引用語義、預設初始化等機制,是寫出正確、高效 Java 代碼的前提。動態創建能力 (`new int[n]`) 讓 Java 擺脫了 C 語言編譯期常量長度的限制,同時保證了記憶體安全。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved