比如:
int[] a=new int[10];
int[10]=1; //越界
java的编译器是如何得知上面的语句越界了的?
本人只会c,c语言里面没有这样强大的检查机制,只有在运行时才会出现各种问题。想了解一下java中这个机制的内部实现原理!
PS:真正懂原理的java高手进,小白误入!觉得分给的少可以加。
没听懂问题的小白真多,受不了!
2. jvm为何能捕获到,数组在运行时是由jvm创建的一个东西,是用机器指令创建的。。。 类似于汇编指令, 先根据你声明的长度分别为每个元素赋值,压栈, 而对于数组的长度也是由一个特定的指令来得到的, 也会压到栈中。这就是你为什么能用a.length得到数组长度的原因, 并且jvm在读写数组元素时都会有与数组长度比较的指令, 如果越界则抛出异常追问
确认一下,java不是在编译时知道的,而是在运行时?
每次读写时,都要做一次判断?
.... 你把你上面那段代码编译一下就知道是编译错误还是运行时错误了, 这种越界错误编译器是检查不出来的, 不运行, 谁也不知道你那个位置是否存了东西
java数组很特别, 它不像c语言的数组, 而更像c语言的字符串, c语言字符串有一个字符串结尾符号, 而java数组在数组的结尾处写了一个数组长度(我不敢确定这样描述是不是正确, 但是数组长度确实是压到栈中了, 并且是在压完数组数据后压的), 这样, jvm通过一条指令就能快速得到数组长度
还有下面同学说的结构体, 有个length属性, 这是不对的, 我之前看过一篇文章就是专门说数组这东西是不是类的问题, 结论是它是一个类, 但是里面没有任何属性和方法, 类名就是 [ , 是一种特殊的原生类, 完全是由jvm临时产生, 而不是程序员写的
没有length属性为什么用.length就能得到长度, 原因就是写jvm的人用机器指令, 可能是汇编什么的直接读栈得到的
每次读写时都要做一次判断, 这个判断是必要的, 如果你不判断, 如何去抛出异常呢
以上本人并没有明确确认过, 但是那片文章里是作者通过分析jvm源码或者通过什么方法确认过的
数组对象,是长度已知的,访问时当然清楚是否越界了。追问
是否可以理解为,java数组对象中包含长度,并不是像C一样单纯的数组?
类似于这样的结构体:
struct array{
int *a;
int length;
}
那是。JAVA里面,所有的都是对象了。而且,本身JAVA代码不允许直接操作内存、等低级的。
在C中可以用一个判断 来防止
比如你想取第四个元素。
Java代码是
int index = 4;
if(index< a.length)
也可以用捕获异常的方法。
C中也可以用类似的判断,但用那个函数,不记得了。本回答被网友采纳
for(int i=0;i<arr.length;i++){
if(i>arr.length){
Ststem.out.println("数组越界了")
}
}