System.arraycopy严格按指定范围复制,需确保srcPos+length≤src.length、destPos+length≤dest.length且length≥0;安全做法是取Math.min(src.length-srcPos, dest.length-destPos)作为实际长度。

System.arraycopy 不会自动适配不同长度的数组,它严格按你指定的源起始位置、目标起始位置和复制长度来操作,超出边界会抛出 ArrayIndexOutOfBoundsException。关键不是“如何处理不同长度”,而是“如何安全地控制复制范围”。
复制长度由你显式指定,而非数组长度决定
arraycopy 的第五个参数 length 是实际要复制的元素个数,它独立于源数组或目标数组的长度。只要满足以下三个条件,就能成功:
- 源数组索引范围:
srcPos到srcPos + length - 1必须在[0, src.length)内 - 目标数组索引范围:
destPos到destPos + length - 1必须在[0, dest.length)内 length ≥ 0
例如:源数组长度为 5,目标数组长度为 3,仍可复制前 3 个元素(length = 3),只要 srcPos = 0、destPos = 0 即可。
常见安全做法:取可用长度的最小值
当想把源数组“尽可能多地”复制到目标数组中(比如做数组扩容或截断),通常手动计算最大安全长度:
立即学习“Java免费学习笔记(深入)”;
- 可用源长度:
src.length - srcPos - 可用目标长度:
dest.length - destPos - 实际复制长度:
Math.min(src.length - srcPos, dest.length - destPos)
这样既不会越界,又能充分利用空间。例如把长度为 10 的数组前 8 个元素复制到长度为 6 的新数组中,最大能复制 Math.min(10 - 0, 6 - 0) = 6 个。
注意:不支持自动类型转换或填充
arraycopy 是内存级拷贝,要求源和目标数组元素类型兼容(如 Object[] → Object[],或子类数组 → 父类数组),但不会做类型检查运行时验证——类型不匹配会在运行时抛 ArrayStoreException。它也不会补零、截断或扩展数组本身,只复制你指定的长度。
替代方案:用 Arrays.copyOf 或流式操作更直观
如果目标是“把一个数组内容复制到另一个长度不同的数组中”,直接用 Arrays.copyOf(src, newLength) 更简单,它内部会创建新数组并自动处理长度逻辑;若需偏移或部分复制,再回到 arraycopy 并手动校验边界。


















