从数组底层运行机制上看,Java没有多维数组一说。所谓多维数组,是说一个引用变量指向的元素也是引用变量。
例如,type[] arrayName
是个指向type类型元素的数组。倘若type也是数组引用变量,比如int[]
,那么这个数组就可以定义为int[][] arrayName
。
在使用引用类型,如
int[]
时,和普通类型没有区别。
按照上述方式定义的二维数组,本质上还是一维数组。为什么这么说呢?因为它的初始化对第二个维度是宽松的:
var arrName = new type[length][];
这里相当于初始化了一个一维数组,这个数组的长度是length,这length个元素的初始值都是null
,这时并没有关心第二个维度的初始化。
为了继续使用这个数组,需要进一步初始化这length个数组,但是这时候,每个元素(数组引用变量)指向的元素的个数是可变的:
public class TwoDimensionTest
{public static void main(String[] args){// 定义一个二维数组int[][] a;// 把a当成一维数组初始化a = new int[4][];// 此时完全可以把a看作是一维数组,遍历a数组的每个元素for (var e : a){System.out.println(e);}// 动态初始化a数组的第一个元素,此时默认a[0]指向的两个元素都是0a[0] = new int[2];a[0][1] = 6;for (var e : a[0]){System.out.println(e);}}
}
- 第19行,在遍历a[0]时,输出应该是0和6。
第二个维度的元素(数组)的大小完全可以不一样:
// 静态初始化
var str1 = new String[][]{new String[3],new String[]{"Hello"}};
// 简化版本
var str2 = {new String[3], new String[]{"Hello"}};
这时str1[0]和str1[1]指向的数组大小是不一样的,在内存中如下图所示: