这段Java代码是如何工作的?

3
public static void main(String[] args)
{
    int [][]shatner = new int[1][1];
    int []rat = new int[4];
    shatner[0] = rat;
    System.out.println(shatner[0][3]);
}    

令人惊讶的是,输出结果为0,为什么Java不检查这种数组越界错误?


2
那么,你发了一个没有问题的答案?在StackOverflow上,通常是先提出问题。 - Justin Niessner
我认为这个问题是假设的 - "为什么会这样呢?" - Bozho
1
这是一个完全合法的问题。 - Matt Greer
如果这是一个 Fortean 数组,你可以访问 shatner[0] 并得到一场青蛙雨……或老鼠……或其他什么东西。 - Nate
@John W. - 现在问题已经修改了四次,我同意你的看法。原始措辞给帖子带来了完全不同的含义。 - Justin Niessner
显示剩余5条评论
7个回答

6

不要感到惊讶。shatner[0]是一个数组(rat),长度为4。因此,shatner[0][3]是rat[3],它恰好是0。


你好nc3b: 那么shatner[0]可以分配给任何大小的int数组吗? int [1] [1]是什么意思?一个int [1]的数组? - chun
1
@chun - int[1][1]的声明设置了数组的初始维度,它基本上是一个包含单个元素的单个数组的数组。 赋值将其更改为一个包含4个元素的单个数组的数组。 在Java中,多维数组的每一行可以具有可变长度。 - justkt

5
你会在哪里看到“indexOutOfBound error”?这段代码的作用如下:
  • 初始化一个大小为1的int数组(大小为1),即2D数组,内容初始化为0
  • 初始化一个大小为4的int数组,内容初始化为0
  • 将2D数组中的单个元素设置为大小为4的一维数组
  • 访问2D数组中第一个数组的最后一个元素,该元素为0

4

没有任何越界的情况。

shatner数组中的第0行会被重新初始化为int[4]


3

并不是Java没有检查IndexOutOfBoundsException。问题在于答案应该是零。关键行是

shatner[0] = rat;

由于这意味着shatner的第0个索引指向长度为4的数组,因此shatner[0][4]是完全有效的。


3

没有数组越界错误。shatner是一个二维数组。你用长度为4的新数组替换了长度为1的第一个数组。所以现在shatner[0][3]是内存中合法的位置。


0

我认为这是因为Java的数组与预期有些不同。你将shatner初始化为[1][1],意思是在内存中类似于{{0},{0}}

然而,你随后将一个整数赋给第一个元素,将其转换为在内存中类似于{{0,0,0,0},{0}},所以Java正在处理新分配的索引。


实际上,在内存中,您拥有一个指向int数组的引用数组。在内存中,这些数组的集群不需要且很可能不会彼此相邻。特别是在他将第一个数组重新分配给rat之后。 - Matt Greer
int[1][1] 是什么意思?是一个 int[ANYSIZE] 的一维数组吗? - chun

0

在Java中,数组不需要是矩形的。这是一个不规则数组,完全没有问题。


我认为要使其成为锯齿状,首先Shatner必须有2行,并且它们的长度不相等。但是这个变量只有1行。 - Phil
即使在绘制时它看起来不像是一个,但从技术上讲它仍然是一个不规则数组。 - Matt Greer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接