java不规则二维数组需分两步定义:先声明外层数组如int[][] data = new int[4][],再逐行初始化每行长度如data[0] = new int[2];其内存结构为“一串指针+若干散块”,外层是连续引用数组,每行子数组独立分配且可能为null,遍历时须判空。

不规则二维数组怎么定义
Java里不规则二维数组(也叫锯齿数组)不是靠一个语句直接“画出表格”,而是分两步搭结构:
-
先声明外层数组容器:用
new int[行数][],比如int[][] data = new int[4][];—— 这只在堆里分配一个含4个null引用的一维数组,没任何实际数据空间 -
再逐行初始化每行长度:必须手动为每一行赋值,例如
data[0] = new int[2]; data[1] = new int[5]; data[2] = new int[1]; data[3] = new int[3];—— 每次new int[n]都在堆中独立开辟一段连续内存 - 不能写
new int[3][4]后再改某一行长度,那只是替换引用,原数组被丢弃,不是真正意义上的“不规则”
内存到底长什么样
它不是一块整齐的矩形内存,而是“一串指针 + 若干散块”:
- 外层是一维引用数组:连续存放在堆中,每个元素是地址(指向某行),初始全为 null
-
每行子数组彼此独立:
data[0]、data[1]等指向的 int[] 分配在堆中任意位置,互不相邻,长度互不影响 -
栈里只存变量名:比如
int[][] data这个变量本身在栈中,它保存的是外层数组首地址,所有数据实体都在堆里
遍历时最容易踩的坑
因为某些行可能是 null,直接按规则数组方式遍历会崩溃:
- 外层循环安全:
for (int i = 0; i 没问题,<code>data.length总是有效 - 内层必须判空:
if (data[i] != null) { for (int j = 0; j ,否则访问 <code>data[i].length就抛NullPointerException - 别对
data[i]直接调用工具方法,比如Arrays.toString(data[i])遇到 null 也会炸
和规则二维数组的关键区别
两者看着像,底层逻辑完全不同:
-
分配时机:规则数组(如
new int[3][4])一步到位,所有子数组同时创建;不规则数组必须两步走,先建架子再填内容 - 内存布局:规则数组各子数组长度一致,JVM倾向于紧凑分配;不规则数组各子数组地址完全离散,无法用统一公式算偏移
-
访问安全边界:规则数组只要下标在
[0,行)和[0,列)内就一定安全;不规则数组多一层风险——得先确认该行存在(非 null),再检查列索引
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











