system.arraycopy不处理异常,需调用方前置校验:1.源/目标起始位置及长度合法;2.非空校验;3.类型兼容性检查;推荐封装带校验的工具方法确保安全。

System.arraycopy 本身不处理异常,它只按参数机械执行;所有异常都由调用方负责预防或捕获。规范的核心不是“怎么 catch”,而是“怎么提前避免”。
必须前置校验的三类越界条件
IndexOutOfBoundsException 不是偶然发生的,而是参数组合违规的必然结果。调用前必须同时确认:
- 源起始位置合法:
srcPos ≥ 0且srcPos + length ≤ src.length - 目标起始位置合法:
destPos ≥ 0且destPos + length ≤ dest.length - 拷贝长度非负:
length ≥ 0(等于 0 时无操作,但不报错)
Null 引用必须独立判空
NullPointerException 与越界无关,但常被误认为是 IndexOutOfBoundsException。它在方法入口即抛出,且不检查后续参数:
-
src == null或dest == null会立即中断执行 - 建议在边界校验前先做
Objects.requireNonNull(src)和Objects.requireNonNull(dest)
类型不匹配引发 ArrayStoreException
该异常发生在运行时拷贝过程中,无法通过静态检查发现:
- 源数组元素类型不能赋值给目标数组元素类型时触发(如 String[] → Integer[])
- 常见于泛型擦除后的 Object[] 向具体类型数组复制,需确保
src.getClass().getComponentType()是dest.getClass().getComponentType()的子类型或兼容类型 - 若不确定,优先用 Arrays.copyOf 并显式传入 Class 对象(如
Arrays.copyOf(src, len, String[].class))
推荐封装带校验的工具方法
重复手写 if 判断易遗漏,也不利于维护。一个轻量、可复用的安全封装示例如下:
public static <t> void safeArrayCopy(T[] src, int srcPos, T[] dest, int destPos, int length) {
Objects.requireNonNull(src, "src must not be null");
Objects.requireNonNull(dest, "dest must not be null");
if (srcPos src.length || destPos + length > dest.length) {
throw new IndexOutOfBoundsException("copy exceeds array bounds");
}
System.arraycopy(src, srcPos, dest, destPos, length);
}</t>
这样既保留 native 性能,又把校验逻辑集中管控,调用处干净清晰。











