system.arraycopy不直接合并数组,仅高效复制内存块;合并需预分配目标数组、分段复制并手动累加偏移量,严格校验null与边界,确保类型精确匹配。

System.arraycopy 本身不直接合并数组,它只做高效内存块复制。要合并大型数组,核心是“预分配 + 分段复制”,关键在控制内存和避免异常。
提前算好总长度,一次性分配目标数组
大型数组合并最忌反复扩容或用集合中转,那样会触发多次 GC 和内存拷贝。必须先遍历所有源数组,累加 length 得到精确总长,再 new 一个目标数组。
- 例如合并 5 个 int[]:a、b、c、d、e,目标长度 = a.length + b.length + c.length + d.length + e.length
- 如果源来自 List 或不确定长度的流,先用 forEach 统计总长,再分配,别用 ArrayList.toArray() 中间转换
- 基本类型数组(如 int[])不能用 Object[] 接收;想统一处理引用类型,目标数组声明为对应父类或接口类型(如 String[] 可放进 Object[],但需确保运行时安全)
按顺序分段调用,偏移量必须手动累加
每次 arraycopy 的 destPos 不是固定值,而是前序所有已复制长度之和。这个累加逻辑不能交给工具自动维护,必须由你控制。
- 复制第 1 个数组:System.arraycopy(a, 0, result, 0, a.length)
- 复制第 2 个:System.arraycopy(b, 0, result, a.length, b.length)
- 复制第 3 个:System.arraycopy(c, 0, result, a.length + b.length, c.length)
- 以此类推——建议用变量记录当前写入位置(如 offset),每次复制后 offset += 当前数组长度
严格校验 null 和边界,否则运行时崩
arraycopy 不做任何防护,参数错一点就抛 ArrayIndexOutOfBoundsException 或 NullPointerException,大型数组出错更难排查。
- 调用前检查每个源数组是否为 null;空数组可跳过,但不能传 null
- 确保 srcPos ≥ 0 且 srcPos + length ≤ src.length
- 确保 destPos ≥ 0 且 destPos + length ≤ dest.length(目标数组长度必须等于总长,不能小)
- length 参数必须是非负整数,别误传字符串的 length() 方法返回值
类型匹配要精确,别指望自动转型
这是大型数组合并最容易踩的坑:JVM 对类型极其严格,尤其基本类型之间完全不兼容。
- int[] 只能复制到 int[],不能到 long[]、Integer[] 或 Object[] —— 否则直接 ArrayStoreException
- String[] 可以复制到 Object[](因为是向上转型),但反过来不行
- 如果需要跨类型拼接(如 int[] 和 double[]),必须自己遍历转换,arraycopy 不参与
- 对象数组只复制引用,不是深拷贝;若原数组后续被修改,目标数组里对应元素也会变
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











