Java中数组拷贝最高效的方式是System.arraycopy,它由JVM底层实现,参数顺序为src、srcPos、dest、destPos、length,需严格校验边界以防ArrayIndexOutOfBoundsException。

Java 中数组拷贝最高效的方式是 System.arraycopy,它由 JVM 底层直接实现,比循环赋值或 Arrays.copyOf 更快,尤其在大数据量场景下优势明显。关键在于参数顺序和边界控制——稍有不慎就会抛出 ArrayIndexOutOfBoundsException 或拷贝错位。
五个参数必须按顺序理解清楚
System.arraycopy(src, srcPos, dest, destPos, length) 这五个参数不能记混:
- src:源数组(非 null)
- srcPos:从源数组哪个索引开始拷贝(>= 0)
- dest:目标数组(非 null,且类型需兼容 src)
- destPos:拷贝到目标数组的起始索引(>= 0)
- length:要拷贝的元素个数(>= 0)
注意:JVM 会校验 srcPos + length 且 <code>destPos + length ,任一不满足就立即抛异常。
常见错误场景与避坑写法
容易出错的是「越界」和「类型不匹配」:
立即学习“Java免费学习笔记(深入)”;
- 把
srcPos当成“拷贝多少个”——其实是起始位置,不是数量 - 目标数组长度不够却没提前检查,比如用
new int[5]接收 10 个元素 - 源数组是
String[],目标却是Object[]——可以;但反过来(Object[]→String[])运行时可能 ClassCastException - 拷贝对象数组时只复制引用,不是深拷贝——这点和数组内容无关,但常被误解
实战建议:什么时候该用、怎么用更稳
不是所有场景都适合直接手写 arraycopy,合理使用才能提效:
- 大批量数据迁移(如日志缓冲区滚动、音视频帧搬运)——优先选它
- 需要部分拷贝(如跳过前 N 个、截取中间段)——比先
Arrays.copyOf再切片更省内存 - 在循环内高频调用时,确保
length计算无误,避免每次重复校验开销 - 不确定目标数组长度?先用
Arrays.copyOf(src, newLength)创建新数组,再用arraycopy填充指定区域(更安全)
一个安全又高效的封装示例
可封装一个带校验的工具方法,兼顾健壮性和性能:
public static <T> T[] copyOfRange(T[] src, int from, int to) {
if (from > to || from < 0 || to > src.length) {
throw new IllegalArgumentException("Invalid range: [" + from + ", " + to + ")");
}
@SuppressWarnings("unchecked")
T[] dest = (T[]) new Object[to - from];
System.arraycopy(src, from, dest, 0, to - from);
return dest;
}
这样既复用了 arraycopy 的高效,又把边界判断显式暴露出来,调用方不易出错。


















