You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于ArrayIndexOutOfBoundException与IndexOutOfBoundsException的异常疑问

为什么ArrayList.get()在不同越界场景抛出不同异常?

这是个很有意思的观察!其实背后是ArrayList的实现细节(以及JDK版本差异)在起作用,咱们一步步拆解:

先看你给出的两段代码

第一段:正数越界触发IndexOutOfBoundsException

public static void main(String[] args) { 
    List<Integer> elements = new ArrayList<>(); 
    elements.add(10); 
    int firstElmnt = elements.get(1); 
    System.out.println(firstElmnt); 
}

当调用get(1)时,ArrayList的当前size是1。在旧版JDK(比如JDK8及以前)的get方法里,会先执行rangeCheck(index)检查:

private void rangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

这里只检查了索引是否大于等于集合大小,1 >= 1成立,所以直接抛出IndexOutOfBoundsException,不会走到访问底层数组的步骤。

第二段:负数索引触发ArrayIndexOutOfBoundsException

public static void main(String[] args) { 
    List<Integer> elements = new ArrayList<>(); 
    elements.add(10); 
    int firstElmnt = elements.get(-1); 
    System.out.println(firstElmnt); 
}

调用get(-1)时,rangeCheck(index)检查-1 >= 1?显然不成立,所以跳过了上层检查,直接进入elementData(index)方法访问底层数组:

E elementData(int index) {
    return (E) elementData[index];
}

而Java数组本身不允许负数索引,这时候访问elementData[-1]就会触发数组的原生异常ArrayIndexOutOfBoundsException。

注意:这不是通用规则!

在JDK9及以后的版本里,ArrayList的get方法实现已经优化了:它改用Objects.checkIndex(index, size)来做索引检查,这个方法会同时验证索引是否小于0和是否大于等于集合大小,并且统一抛出IndexOutOfBoundsException。也就是说,新版本里不管是正数越界还是负数索引,都会抛出同一种异常。

总结

你看到的差异是旧版JDK中ArrayList的检查逻辑漏洞导致的:上层只拦截了“索引过大”的情况,没拦截“索引为负”的情况,让后者直接触发了底层数组的异常。并不是“负数索引必然触发ArrayIndexOutOfBoundsException”的通用规则哦。

内容的提问来源于stack exchange,提问作者Priya Rastogi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:26:35