system.arraycopy抛出indexoutofboundsexception的根本原因是任一索引参数越界,即srcpos、destpos或length超出对应数组有效范围;它仅做基础边界校验,不检查逻辑合理性,需调用前显式校验而非依赖try-catch。

调用 System.arraycopy 时抛出 IndexOutOfBoundsException,根本原因是传入的任意一个索引参数(源起始位置、目标起始位置、复制长度)超出了对应数组的有效范围。它不检查“逻辑合理性”,只做最基础的边界校验——只要越界就立刻报错。
确认每个参数的合法范围
该方法签名是:System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
五个参数都必须满足以下条件:
- src != null 且 srcPos ≥ 0 且 srcPos + length ≤ src.length
- dest != null 且 destPos ≥ 0 且 destPos + length ≤ dest.length
- length ≥ 0(为 0 是合法的,表示不复制)
常见错误:把 src.length 当成最大可复制数,却忘了还要预留 srcPos 的偏移;或误以为 length 是“到某索引为止”,实际它是“复制多少个元素”。
在调用前做显式校验
不要依赖 try-catch 捕获这个异常来“兜底”,而应在调用前主动判断。例如:
// 安全复制:取能复制的最大长度int copyLen = Math.min(src.length - srcPos, dest.length - destPos);<br> copyLen = Math.max(0, copyLen); // 防负数<br> System.arraycopy(src, srcPos, dest, destPos, copyLen);
如果业务逻辑要求必须复制指定长度,那就提前校验并给出明确提示:
if (srcPos src.length ||<br>
destPos dest.length ||<br>
length src.length || destPos + length > dest.length) {<br>
throw new IllegalArgumentException("arraycopy 参数越界: src[" + srcPos + "," + (srcPos+length) + "], dest[" + destPos + "," + (destPos+length) + "]");<br>}
System.arraycopy(src, srcPos, dest, destPos, length);
注意数组类型和引用安全
虽然 System.arraycopy 支持基本类型和对象数组,但若 src 和 dest 类型不兼容(如源是 String[],目标是 Integer[]),会在运行时抛 ArrayStoreException,不是 IndexOutOfBoundsException。不过这类问题常和越界混在一起排查,建议:
- 确保两个数组是相同组件类型,或目标数组类型是源数组组件类型的父类/接口
- 避免用 Object 数组接收后随意转成子类型数组再复制
- 调试时打印
src.getClass()和dest.getClass()确认类型匹配
用 Arrays.copyOf 替代部分场景
如果你只是想从头开始复制一个子数组(比如截取前 N 个元素),直接用 Arrays.copyOf(src, newLength) 或 Arrays.copyOfRange(src, from, to) 更安全、语义更清晰,它们内部已封装了边界检查,且自动处理扩容逻辑。
例如:String[] sub = Arrays.copyOfRange(original, 2, 5); —— 复制索引 2、3、4 元素,无需手动算 length。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











