Java多维数组-为什么只定义第一个大小就足够了?

Java多维数组-为什么只定义第一个大小就足够了?,java,arrays,multidimensional-array,instantiation,Java,Arrays,Multidimensional Array,Instantiation,使用以下Java示例: int[] array1 = new int[]; // Incorrect, since no size is given int[] array2 = new int[2]; // Correct int[][][] array3 = new int[][][]; // Incorrect, since no size is given int[][][] array4 = new int[2][2][2]; // Correct int[][][] array5 =

使用以下Java示例:

int[] array1 = new int[]; // Incorrect, since no size is given
int[] array2 = new int[2]; // Correct
int[][][] array3 = new int[][][]; // Incorrect, since no size is given
int[][][] array4 = new int[2][2][2]; // Correct
int[][][] array5 = new int[2][][]; // Correct (why is this correct?)
所以,我的问题是,为什么只分配多维数组的第一个大小就足够了?我以为您总是必须分配一个大小,即使是多维数组的每个单独数组部分,但今天我发现
array5
也是Java的正确方法。现在我只是想知道为什么。有人能举例说明为什么这适用于多维数组和/或其背后的原因吗

此外,我猜以下情况也适用:

int[][][] array6 = new int[][2][]; // Incorrect
int[][][] array7 = new int[][][2]; // Incorrect
int[][][] array8 = new int[][2][2]; // Incorrect
int[][][] array9 = new int[2][2][]; // Correct
int[][][] array10 = new int[2][][2]; // Incorrect?? (Or is this correct?)
我现在有点困惑,如果有人知道的话,我想澄清一下


编辑/半解析:

好的,我找到了第一部分工作的原因:

int[][] array = new int[2][];
array[0] = new int[5];
array[1] = new int[3];
// So now I have an array with the following options within the array-index bounds:
// [0][0]; [0][1]; [0][2]; [0][3]; [0][4]; [1][0]; [1][1]; [1][2]
// It basically means I can have different sized inner arrays
唯一需要回答的问题是:

int[][][] array10 = new int[2][][2]; // Incorrect?? (Or is this correct?)

是否有效。

因为您没有定义多维数组。实际上,您定义的是一个数组,数组是
int
s的数组。例如,您可以这样做:

int[][] array1 = new int[5][];
for(int i = 0; i < 5; i++){
    array1[i] = new int[i];
}
虽然这不是:

int[][] arr = new int[2][2];
arr[][0] = new int[3];
因为

int[][][] array = new int[n][m][p];
相当于创建n维数组,然后用m维数组的n个实例的引用填充该数组,然后用p维数组的m个实例的引用填充该数组


当并非所有维度都存在时,您已经部分初始化了数组。

简单地说:二维数组是数组的数组。Java中的数组是对象。因此,仅定义第一个大小就创建了一个给定大小的数组,该数组可以存储其他数组,但此时这些数组仍然为空。因此,在使用它之前,您需要调用类似于
array1[0]=newint[5]
的函数,否则您将得到一个NullPointerException。 对于更多维度的数组,这将相应地适用

理论上,所有的“内部”数组实际上可以有不同的长度。因此您可以编写如下内容:
array1[0]=newint[1];数组1[1]=新整数[4]

关于你的最后一个问题: 这是无效的,Java编译器会说“不能在空维度之后指定数组维度”。这是因为没有指定第二级,因此在第一级数组中是空对象,因此,不能在这些空数组上指定维度

int[][][] array5 = new int[2][][]; // Correct (why is this correct)
编写此命令可以实例化int[]数组。在内存中,它是对int[]的引用数组。您不需要知道int[][]的大小,因为它只是一个引用,每个int[]的大小可能不同

以这种方式查看内存:

array5:[length a ref, length of a ref]
然后实例化子阵列0:

... ,subArray0[ length of a ref, length of a ref], ...
并将子阵列影响到主阵列

array5:[refToSubArray0, length of a ref],
但不管th子数组的长度如何,您只需要将引用的长度保存在内存中以存储子数组,因为它存储在其他位置

int[][][] array10 = new int[2][][2]; // Correct?? (Is this correct?)
这是不对的。我相信当你这么做的时候

new int[2][2][2]
您可以在内存中分配:

array[ref0,ref1], sub0[ref00,ref01], sub1[ref10,ref11], sub00[int000, int001], sub00[int000, int001], sub01[int010, int011], sub10[int100, int101], sub11[int110, int111] ...
如果跳过数组大小,它将无法为第三个子数组分配内存,因为它不知道将实例化多少个子数组

array[ref0,ref1], sub0[ref00,ref01], sub1[ref10,ref11], sub00[int000, int001], sub00[int000, int001], sub01[int010, int011], sub10[int100, int101], sub11[int110, int111] ...