Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么不是';ArrayIndexOutOfBoundsException不是编译时错误吗?_Java_Compilation_Indexoutofboundsexception_Compile Time - Fatal编程技术网

Java 为什么不是';ArrayIndexOutOfBoundsException不是编译时错误吗?

Java 为什么不是';ArrayIndexOutOfBoundsException不是编译时错误吗?,java,compilation,indexoutofboundsexception,compile-time,Java,Compilation,Indexoutofboundsexception,Compile Time,有人能解释一下为什么ArrayIndexOutOfBoundsException是运行时异常而不是编译时错误吗? 在索引为负数或大于数组大小的明显情况下,我不明白为什么它不能成为编译时错误 编辑:特别是当数组的大小甚至索引在编译时已知时,例如int[]a=newint[10];a[-1]=5这应该是一个编译错误。使用指针时,如果正确保留了要访问的内存位置,则可能会有负索引,并且不会出现错误。这里有一个例子。当使用低级编程语言时,像这样的事情经常会发生,但它们在高级语言中没有太多意义,至少对我来说

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


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

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

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.
这可能会产生一个非常有用和有趣的结果:


因为它不能在编译时一直被检测到。

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


因此,不可能在编译时通过检查数组的访问而不知道其边界(大小)来检查此类异常。

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


检查此问题以了解更多信息:。

我同意不能在编译时检查数组大小这一事实,我想补充另一个关于数组大小限制的注意事项,数组大小应在primitive
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对象。

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


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

,但是当大小在编译时定义,甚至索引在编译时也是负数时。。。。那么为什么编译器不能生成错误消息呢?虽然你可以找出编译器可能捕捉到的明显的例子,但它们不是常见的原因;是斯内基的人让你着迷。我从未打过
a[-1]=5或类似。数组上的1-over-large for循环对于刚开始(尤其是来自1-indexed语言的人)的人来说是非常常见的,如果捕获到这一点会很好,但是编译器开始实际运行部分代码,以捕获只有新手程序才能做的事情。编译阶段需要花费时间我同意编译器不检查数组索引的循环是好的,但仍然是a[-1]=5;应该是编译错误,如[1.5]=5;当我们使用十进制数时。我敢打赌,我们中没有人使用十进制数作为索引,这也不例外。这和其他答案根本没有解决这个问题。当然,在这种情况下编译器无法捕获它;问题是,在涉及一个常量的情况下,编译器确实知道它将抛出一个异常,为什么它不给出一个编译时错误呢?您对文章的编辑是完全无关的。这是一个Java问题,不是C问题。