Java 如何';s未指定某个索引时为多维数组分配的内存

Java 如何';s未指定某个索引时为多维数组分配的内存,java,arrays,memory,Java,Arrays,Memory,假设我有一个Java程序 int[5][] array; arr[0]= getMeArray(var); arr[1]= getMeArray(var); ..and so on public int[] getMeArray(int var){ if(var == 0) return new int[9]; else return new int[5]; } 现在,内存分配是在编译时完成的,因为按照我的理解应该这样做,但我不确定如何计算应该分配多少给数组。在Java中,该程序

假设我有一个Java程序

int[5][] array;
arr[0]= getMeArray(var);
arr[1]= getMeArray(var);
..and so on

public int[] getMeArray(int var){
 if(var == 0)
  return new int[9];
 else
  return new int[5];
}

现在,内存分配是在编译时完成的,因为按照我的理解应该这样做,但我不确定如何计算应该分配多少给数组。

在Java中,该程序不起作用。您需要更改此行:

int[5][] array;
致:

所有数组分配都在运行时进行。这将分配一个
int[]
数组(实际上是一个引用数组),所有数组最初都设置为
null
。Java根本没有多维数组,即由多个下标索引的单个内存块。相反,它只有数组的数组

现在,内存分配是在编译时完成的,因为它应该按照我的理解完成吗

不,这就是它在C中的工作原理。Java数组是完全不同的

但我不知道如何计算应该分配多少给数组

您的意思是将为阵列分配多少内存

多维数组是对数组对象的引用数组


对对象的引用占用固定的空间量,比如说B字节。
int
数组每个整数大约需要4个字节,再加上额外的4个字节来存储其大小(所有Java数组都是这样)。因此,对于您的示例,对于每个子数组,它将是
5*B+4+
4倍于每个子数组的大小+4。子数组仅在程序实际创建时分配。这对于所有阵列都是正确的,它们仅在由程序创建时分配。我的计算假设包括子数组在内的所有内容都已创建。

我假设您打算编写以下内容:

int[][] array = new int[5][];  // this compiles
现在,回答您的问题:变量
array
只是一个引用;内存被它指向的任何东西所消耗。在本例中,它指向
int[]
s的数组。具体来说,它指向一个引用数组,每个引用都指向一个
int[]

+-----+-----+-----+-----+-----+ array ----------> | [0] | [1] | [2] | [3] | [4] | +-----+-----+-----+-----+-----+ | | | | | | | | | | | | | | | v v v v v +-----+ ... ... ... ... | 0 | +-----+ | 0 | ... +-----+-----+-----+-----+-----+ 数组------->|[0]|[1]|[2]|[3]|[4]| +-----+-----+-----+-----+-----+ | | | | | | | | | | | | | | | v v v v +-----+ ... ... ... ... | 0 | +-----+ | 0 | ...
水平数组首先分配
新int[5][]
(这会消耗内存)。然后,当您在
getMeArray()
中分配每个整数数组时,内存会进一步消耗。这是一种运行时现象

二维数组是数组的数组。第一个数组包含对其他数组的引用。因此,存储n个引用所需的内存已分配


当调用methid
getmearray
时,第二维度数组的内存稍后分配。

Java数组声明只是引用。因此,
int[5][]数组
将无法编译。您只能声明一个二维数组,如
int[][]array
,这样它将显示
array
是对二维数组的引用。 数组的大小是在运行时确定的,而不是在编译时确定的。因此可以编写如下代码:

public void main() {
    int[][] test = new int[get()][];
}
int get() {
    return (int) (Math.random() * 10);
}

即使像
int[][]array=new int[5][]
这样声明大小,也不会在运行前确定
数组的大小。这也解释了为什么Java中没有像
sizeof
这样的操作符,而且没有意义。

您的意思是在这种特定情况下还是在一般情况下?
public void main() {
    int[][] test = new int[get()][];
}
int get() {
    return (int) (Math.random() * 10);
}