【Java源码】ArrayList源码(上)关于get方法的遗留问题
问题重现
在ArrayList源码的get方法中,传参为负的异常是如何产生的?
源码只判断了index > size
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size;
}
@SuppressWarnings("unchecked")
E elementData(int index) {
return (E) elementData[index];
}
为了弄清楚这个问题,我发了个帖子,好在得到了完美的回答
在此鸣谢 用户 Surrin1999
为了方便,现在将他的解释拿过来看
授人以鱼不如授人以渔 为了把这个问题讲好 我们复现一次这个问题
测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
在第11行打一个断点 然后进入debug(调试)模式 然后点击单步跳入(注意不是单步跳过 不知道的话后面的图会有提到)
显然 你也知道rangeCheck只是检测了index > size 那么问题自然出在return这里
继续单步跳入
你会发现 此时忽然进入了一个异常类里面 再结合我的红色箭头 想必你已经猜到一点了
继续单步跳入
很明显了 return时抛出的异常不是ArrayList里调用的 是jvm检测到数组越界而自动抛出的通过跳入到这里我们可以知道 上面那个异常类是继承自RuntimeException 而只有继承自Exception的异常才需要在源码中显式定义 这一张图里的红色箭头指向就是单步跳入 它右边的就是单步跳过
总结 :遇到一些匪夷所思的问题 很多时候我们只要拆分为一小块慢慢剖析,如打断点调试,就能缩小问题的范围,最终找出答案所在 希望能对你有帮助
这个问题的产生也在于自己忽视了JVM本身的一些东西,只在意了代码方面的实现,忽视底层原理,要想把一个东西学好,其底层是没办法忽略的,受益匪浅,谢过大佬!