运行时修改二维数组列大小的合理性:为何未触发数组越界异常?
为什么Java中二维数组可以替换子数组为不同长度的一维数组?
嘿,这个问题问得特别到位,刚好戳中了Java二维数组最容易被误解的点——Java里没有真正意义上的“二维数组”,它本质上是数组的数组,也就是一个一维数组,每个元素本身又是另一个独立的一维数组。下面一步步给你拆解原因:
1. 先看你的初始化语句到底做了什么
当你写:
String[][] arr = new String[2][2];
这段代码其实完成了两个操作:
- 首先创建了一个长度为2的一维数组
arr,它的每个元素类型是String[](也就是一维字符串数组); - 然后自动给
arr[0]和arr[1]分别初始化了一个长度为2的String[]数组,作为它们的初始值。
注意:这里只是给arr[0]和arr[1]赋了初始的数组引用,并没有把它们的长度“固定死”——它们只是普通的String[]类型变量,随时可以被赋值为其他同类型的数组引用。
2. arr[0] = a; 是引用赋值,不是修改数组维度
当你执行:
String a[] = { "1", "2", "3", "4", "5" }; arr[0] = a;
这只是把a这个数组的引用地址赋值给了arr[0],替换掉了它原来指向的那个长度为2的数组。相当于:
- 原来
arr[0]指向A数组(长度2); - 现在让
arr[0]指向B数组(也就是a,长度5)。
整个过程没有修改任何数组的维度,只是换了arr[0]这个变量指向的对象而已,完全符合Java的类型规则(arr[0]是String[]类型,a也是String[]类型),所以不会报错。
3. 为什么没有数组越界异常?
数组越界异常(ArrayIndexOutOfBoundsException)只会在你访问了数组不存在的索引时抛出,比如你去读a[5](a的长度是5,索引范围是0-4)。而这里的操作只是赋值引用,根本没有访问数组的索引,自然不会触发异常。
你甚至可以继续做这样的操作:
arr[1] = new String[10];
这时候arr[1]就指向了一个长度为10的数组,此时arr的两个子数组长度分别是5和10,这在Java里是完全合法的——这种数组也被称为参差不齐数组(Jagged Array)。
验证一下
你可以在代码里加两行打印:
System.out.println(arr[0].length); // 输出5 System.out.println(arr[1].length); // 输出2
就能直观看到两个子数组的长度已经不一样了。
内容的提问来源于stack exchange,提问作者hermit
相关产品推荐
相关产品推荐

