C代码段: -
int ary[100];
for (int i = 0; i < 100; i ++)
{
dosomething();
}
java-code snippet: -
int [] ary = new int (100); // int ary [] …
for (int i = 0; i < ary.length; i++)
do_something();
在C代码中,它可能导致分段错误,但在Java代码中由于长度元数据,它将
没有发生。有人详细解释了吗?
答案 0 :(得分:1)
JVM在运行时进行各种安全检查,包括边界检查。因此,您不会因尝试访问阵列外的位置而遇到段错误,但您将获得ArrayIndexOutOfBoundsException
。这是使用(半)解释语言的好功能之一。
答案 1 :(得分:1)
访问数组的C代码假定程序员知道他在做什么,所以它永远不会为你检查数组索引。如果要检查数组索引,则必须自己执行此操作。如果你不检查索引,并且结果是在数组的内存分配区域之外,则它是未定义的行为,这可能会导致分段错误。遗憾的是,未定义的行为并不总是导致崩溃,因此很长一段时间内都可能会忽略错误。
另一方面,在Java中,编译器不信任您做正确的事情。它将数组的长度与数组一起存储,并在访问数组之前检查您的索引是否为非负数。
请注意,这可以防止未定义的行为,但它不一定能防止崩溃:如果您的程序试图访问有效范围之外的索引,JVM会抛出运行时异常,这会导致程序崩溃,除非您抓住例外。这种方法的优点是您的程序在错误的读取或写入可能造成任何伤害之前快速失败。
答案 2 :(得分:1)
详细说明,JVM只是在运行时向最终字节码组件添加“魔术代码”,其中包括以下形式检查as specified的边界:
if (i < 0 || i >= length) throw new ArrayIndexOutOfBoundsException();
这当然必须为每次访问完成,并且通过简单的实现可以减慢阵列访问速度。然而,有许多尝试通过this或this等更复杂的想法来规避这一点。 Google可以帮助您找到更多信息。
有些JVM可能已经使用了更复杂的方法,而其他JVM只是将上面的检查添加到在运行时执行/编译代码期间访问数组索引的每条指令。