java不规则二维数组声明为int[][] arr,先new int[3][]分配外层数组,再逐行如arr[0]=new int[2]、arr[1]=new int[5]初始化;不可用new int2后修改子数组长度,否则导致逻辑错误。

Java不规则二维数组怎么声明和创建
Java里没有真正的“多维数组”,只有“数组的数组”。所谓不规则二维数组,本质是一维int[][],但每个子数组长度可以不同。声明时不能写int[3][4]这种固定尺寸——那会强制规则化,也不允许在声明时直接指定子数组长度。
正确做法是先声明引用,再逐层分配内存:
-
int[][] arr:只声明引用,arr为null -
arr = new int[3][]:分配外层数组,含3个null元素 -
arr[0] = new int[2]、arr[1] = new int[5]……分别初始化每行
常见错误:用new int[2][3]初始化后强行改子数组长度
一旦用了new int[2][3],就创建了规则二维数组:外层2个元素,每个都是长度为3的int[]。此时arr[0] = new int[5]语法合法,但容易误以为是在“扩容”,其实只是把arr[0]指向了一个新数组——原arr[0](长度3的那个)会被GC回收。这不是“修改长度”,而是替换引用。
更隐蔽的坑是:如果后续代码仍假设所有行长度一致(比如循环用arr[0].length当统一列数),就会在arr[1]被重新赋值为不同长度后出错。
立即学习“Java免费学习笔记(深入)”;
- 错误假设:
for (int j = 0; j 遍历所有行的列 - 实际应改为:
for (int j = 0; j ,其中<code>i是当前行索引
初始化时直接用大括号嵌套赋值的写法
想一步到位写死内容,可以用静态初始化语法,但必须保证每行大括号内元素数量可不同:
int[][] jagged = {
{1, 2},
{3, 4, 5, 6},
{7}
};
这种写法本质等价于先new int[3][],再逐行new int[2]、new int[4]、new int[1]并赋值。编译器自动推导外层数组长度为3,每行长度按大括号内逗号分隔个数确定。
- 不能写成
int[][] arr = new int[][] {{1,2}, {3,4,5}};——虽然合法,但冗余,大括号初始化已隐含new - 不能混用:比如
{ {1,2}, null, {3} }合法(null表示该行未初始化),但访问arr[1].length会抛NullPointerException
遍历不规则数组时最容易忽略的空指针风险
不规则数组某一行可能是null(比如只分配了外层new int[5][],但没给arr[2]赋值),这时候直接调用arr[i].length或arr[i][j]就会崩。
- 安全遍历必须加判空:
if (arr[i] != null) for (int j = 0; j - 增强for循环
for (int[] row : arr)本身不会空指针,但进内层循环前仍要检查row != null - 工具类如
Arrays.deepToString(arr)能安全处理null行,但打印出来是"null"字符串,不是跳过
不规则数组的“不规则”不只是长度差异,更是引用状态的不确定性——null行的存在让每次访问都得带防御逻辑,这点比C/C++里的指针数组更隐蔽,也更容易漏掉。










