【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

import java.util.ArrayList;

 

public class TestList {

    public static void main(String[] args) {

        ArrayList<Integer> list = new ArrayList<>();

        list.add(1);

        list.add(2);

        list.add(3);

        list.add(4);

         

        System.out.println(list.get(-1));

    }

}



在第11行打一个断点 然后进入debug(调试)模式  然后点击单步跳入(注意不是单步跳过  不知道的话后面的图会有提到)


显然 你也知道rangeCheck只是检测了index > size  那么问题自然出在return这里

继续单步跳入



你会发现 此时忽然进入了一个异常类里面 再结合我的红色箭头 想必你已经猜到一点了

继续单步跳入



很明显了    return时抛出的异常不是ArrayList里调用的 是jvm检测到数组越界而自动抛出的通过跳入到这里我们可以知道 上面那个异常类是继承自RuntimeException  而只有继承自Exception的异常才需要在源码中显式定义    这一张图里的红色箭头指向就是单步跳入 它右边的就是单步跳过

总结 :遇到一些匪夷所思的问题 很多时候我们只要拆分为一小块慢慢剖析,如打断点调试,就能缩小问题的范围,最终找出答案所在 希望能对你有帮助

 

这个问题的产生也在于自己忽视了JVM本身的一些东西,只在意了代码方面的实现,忽视底层原理,要想把一个东西学好,其底层是没办法忽略的,受益匪浅,谢过大佬!

全部评论

相关推荐

10-27 17:26
东北大学 Java
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
11-20 19:57
已编辑
某大厂 golang工程师 23.0k*16.0, 2k房补,年终大概率能拿到
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务