为什么ArrayIndexOutOfBoundsException不是编译时错误?

时间:2014-05-09 15:58:36

标签: java compilation indexoutofboundsexception compile-time

有人可以向我解释为什么ArrayIndexOutOfBoundsException是运行时异常而不是编译时错误? 在明显的情况下,当索引为负数或大于数组大小时,我不明白为什么它不能成为编译时错误。

已编辑:尤其是在编译时已知数组的大小甚至索引时,例如int[] a = new int[10]; a[-1]=5;这应该是编译错误。

6 个答案:

答案 0 :(得分:4)

可以仅在运行时定义数组的大小(例如,最简单的情况,如果数组的大小取决于用户输入)。

因此,在编译时检查数组的访问而不实际知道它的边界(大小)是不可能在编译时检查的。

答案 1 :(得分:3)

因为无法在编译时始终检测到它。

答案 2 :(得分:1)

输入a[-1] = 5;只是新手会做的事情(正如Richard Tingle所说)。因此,仅为此类错误更新语言标准是不值得的。更有趣的情况是a[SOME_CONSTANT] = 5;其中SOME_CONSTANT被定义为static final int SOME_CONSTANT = -1;(或某些表达式仅涉及计算-1的常量)。但是,即使这样,如果编译器将此标记为错误,它也可能会遇到程序员已将a[SOME_CONSTANT] = 5;放入已检查该常量负值的if语句中的情况。 (我在这里假设SOME_CONSTANT是一个常量,如果应用程序的需求发生变化,其值可能会改变。)因此,从理论上讲,语言可能会使编写数组索引操作成为非法那可能不会成功,有充分的理由不这样做。

P.S。这是一个真正的问题。 Ada语言确实对静态表达式进行了一些编译时检查,这些表达式无法成功,但是它没有检查这种情况,并且在过去几周内已经讨论过它是否应该,或者是否应该允许编译器(但不是必需的)拒绝具有已知失败的数组索引的程序。

答案 3 :(得分:0)

使用指针时,如果您正确保留了将要访问的内存位置,则可能有负索引并且没有错误。这是一个例子。使用低级编程语言时,像这样的事情很常见,但是在高级语言中它们没有多大意义,至少对我来说是这样。

int arr[10];
int* p = &arr[2];

int x = p[-2]; // valid:  accesses arr[0]

如果您尝试这样做:

arr[-5] //you will access and invalid block of memory, this why you get the error.

这可能会带来非常有用和有趣的信息:

http://www-ee.eng.hawaii.edu/~tep/EE160/Book/chap7/subsection2.1.3.2.html

答案 4 :(得分:0)

在编译时无法检查所有索引,因为它们可以是变量,其值可以在运行时更改。如果您有array[i]i是读取文件的结果,则可以在执行程序时评估i。即使您使用变量,请记住您可以重新分配您的阵列以更改其容量。同样,这只能在运行时检查。

查看此问题以获取更多信息:Runtime vs Compile time

答案 5 :(得分:0)

除了同意在编译时无法检查数组大小这一事实之外,我想在数组大小的限制上添加另一个注释,预计它将在原始范围内int

// This compiles, because the size evaluates to an integer.
int[] array = new int[Integer.MAX_VALUE + 1];

// This doesn't compile.
int[] array = new int[Long.MAX_VALUE];

这个错误是因为length字段(int)是特殊Java对象的数组。