Java多维数组本质是“数组的数组”,外层数组存int[]引用,内层数组独立分配于堆中,物理不连续但每行内部连续;支持不规则结构,访问需两次寻址。

多维数组在 Java 中不是“真正”的多维结构,而是“数组的数组”,这个本质直接决定了它在 JVM 内存模型中的布局方式——外层数组和内层数组各自独立分配在堆中,彼此通过引用连接,而非连续一块内存。
堆中分层存储:外层数组存引用,内层数组存数据
声明 int[][] matrix = new int[3][4] 时:
- JVM 在堆中创建一个长度为 3 的一维数组(外层数组),每个元素类型是
int[],初始值全为null - 接着为每一行分别分配一个长度为 4 的
int[]数组(内层数组),并让外层数组对应位置指向它们 - 栈中只保存变量
matrix这个引用,指向外层数组的首地址
这意味着:三行可能分散在堆的不同位置,不保证物理连续;但每行内部的 4 个 int 是连续存储的。
支持“锯齿结构”:源于引用灵活性
正因为每行都是独立的 int[] 对象,你可以手动构造不规则形状:
立即学习“Java免费学习笔记(深入)”;
-
int[][] jagged = new int[3][];—— 只分配外层数组 jagged[0] = new int[2];jagged[1] = new int[5];jagged[2] = new int[1];
这种结构完全合法,也印证了多维数组本质是“引用的引用”,而非传统意义上的二维连续块。
访问过程涉及两次寻址
执行 matrix[i][j] 时,JVM 实际做两步:
- 先根据
matrix引用找到外层数组 → 定位第i个元素(即某个int[]的引用) - 再解引用该地址,跳转到对应内层数组 → 按偏移
j找到具体int值
相比一维数组的一次寻址,多维数组有轻微间接开销,但仍是 O(1) 时间复杂度。
与一维数组的关键区别:内存连续性
一维数组(如 int[100])所有 100 个 int 在堆中严格连续;而二维数组 int[10][10] 至少包含 11 个独立对象(1 个外层 + 10 个内层),它们的内存地址彼此无关。这也解释了为何 Arrays.equals() 对二维数组无效,必须用 Arrays.deepEquals() —— 它递归比较每一层引用所指向的内容。


















