system.arraycopy不会自动防越界,需调用前手动校验;其越界异常由源/目标位置或长度非法触发;推荐用safecopy封装校验逻辑,或根据场景改用arrays.copyof。

System.arraycopy 不会自动防越界,它只管搬数据——参数一错,当场抛 ArrayIndexOutOfBoundsException。真正起防护作用的,是你调用前的校验逻辑。
越界异常的三大硬性触发条件
以下任一不满足,方法还没开始复制就直接中断并报错:
- 源位置非法:srcPos src.length(注意是“大于”,等于刚好合法)
- 目标位置非法:destPos dest.length
- 长度非法:length
最易踩坑的四个动态场景
这些地方看着逻辑通顺,运行却崩得毫无征兆:
- 动态索引未重算边界:比如 srcPos = offset + headerLen,不能只检查 offset ≥ 0,必须验证 offset + headerLen + length ≤ src.length
- 复用旧 length 值:源数组被截断、过滤或重建后,仍沿用之前缓存的 length,导致实际可用长度已不足
- 混淆 length 和 end 下标:length 是元素个数,不是结束索引;destPos + length 才是目标区域末尾的下一个位置
- 字节流中忽略长度头解析:反序列化时若先读 payload 长度 L,却未确认 L ≤ 剩余字节数,就直接 arraycopy,极易越界
推荐的安全封装写法
把校验收口到一个工具方法里,兼顾性能与可维护性:
public static <t> void safeCopy(T[] src, int srcPos, T[] dest, int destPos, int length) {
if (src == null || dest == null) {
throw new NullPointerException("source or destination array is null");
}
if (srcPos src.length || destPos + length > dest.length) {
throw new IndexOutOfBoundsException("copy range exceeds array bounds");
}
System.arraycopy(src, srcPos, dest, destPos, length);
}</t>
调用时只需一行 safeCopy(src, 2, dst, 0, 10),不再担心漏判。
什么情况该换 Arrays.copyOf
如果你不需要往已有数组里填数据,而是想“新建 + 拷贝”,就别硬套 arraycopy:
- 目标容量不确定:Arrays.copyOf(src, newLength) 自动处理扩容、新建、拷贝三步,内部已做完整校验
- 仅需浅拷贝整个数组:Arrays.copyOf(src, src.length) 比手写 arraycopy 更简洁安全
- 需要类型保障:Arrays.copyOf(src, len, String[].class) 可在编译期约束目标类型,避免 ArrayStoreException
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











