system.arraycopy拼接数组更轻量可控,需先计算总长度并预分配空间,再分段复制;可封装为支持多数组的工具方法,但须校验null及边界条件。

直接用 System.arraycopy 拼接数组,比新建 ArrayList 再转回数组更轻量、更可控,尤其适合已知目标长度或追求极致性能的场景。
明确目标数组长度,一次性分配空间
拼接前必须算出总长度,避免多次扩容。比如拼接两个 int 数组 a 和 b:
int[] a = {1, 2, 3};
int[] b = {4, 5};
int[] result = new int[a.length + b.length];
这是关键前提——System.arraycopy 不负责扩容,只做内存块复制。
分段调用 arraycopy,按序填充
每一段源数组对应目标数组的一个连续区间。继续上面的例子:
- 把
a复制到result[0]开始的位置:System.arraycopy(a, 0, result, 0, a.length); - 把
b复制到result[a.length]开始的位置:System.arraycopy(b, 0, result, a.length, b.length);
注意第三个参数(目标起始索引)要动态计算,不能写死。
支持多数组拼接,可封装为工具方法
三个及以上数组时,手动写多行 arraycopy 易错。推荐封装通用方法:
public static int[] concat(int[]... arrays) {
int totalLen = 0;
for (int[] arr : arrays) totalLen += arr.length;
int[] result = new int[totalLen];
int pos = 0;
for (int[] arr : arrays) {
System.arraycopy(arr, 0, result, pos, arr.length);
pos += arr.length;
}
return result;
}
该模式适用于任意基本类型数组(需重载)或 Object[],但不适用于泛型数组(因类型擦除无法保证运行时类型安全)。
注意边界与 null 安全
实际使用中容易忽略这些细节:
- 任一输入数组为
null时,arraycopy会抛NullPointerException,建议提前校验; - 源数组长度为 0 时无害,但若传入负数长度会抛
ArrayStoreException; - 目标数组容量不足(即
pos + length > result.length)也会触发异常,务必确保预分配正确。
不复杂但容易忽略。











