system.arraycopy是java中最高效的标准数组拷贝方式,但需严格遵循参数顺序(源、源偏移、目标、目标偏移、长度)、类型兼容性(如string[]→object[]可行,反之抛arraystoreexception)及边界约束(srcpos+length≤src.length等),否则易致静默覆盖或运行时异常;小数组(≤4元素)可能因jni开销反而更慢,中大型数组性能显著优于手动循环。

直接用 System.arraycopy 是 Java 里最快的标准数组拷贝方式,但快的前提是用对——参数顺序错、类型不匹配、小数组滥用,反而拖慢性能。
参数顺序别记反:源→源偏移→目标→目标偏移→长度
签名是 System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)。最容易写错的是把源起始索引和目标起始索引位置搞混,比如本想从 src[2] 拷 3 个到 dest[0],却写成 arraycopy(src, 0, dest, 2, 3),结果覆盖了 dest[2] 和 dest[3]。
- 口诀:“源、源偏移、目标、目标偏移、数几个”
-
length是元素个数,不是结束下标 - 所有索引和
length必须 ≥ 0,且srcPos + length ≤ src.length,destPos + length ≤ dest.length
只认同类型:基本类型不互通,对象数组看继承关系
它不做任何类型转换,编译期只检查引用兼容性,运行时才校验元素类型。
-
int[]不能拷到long[],哪怕长度一致也不行 -
String[]可以拷到Object[](子类→父类) -
Object[]拷到String[]会抛ArrayStoreException,而且已拷成功的部分不会回滚 - 若需跨类型转换(如
int[] → Integer[]),必须用Arrays.stream()等方式,但性能损失明显
大小要心里有数:大数组优势明显,极小数组慎用
对长度 ≤ 4 的数组,JNI 调用开销可能超过简单赋值;HotSpot 虽有内联优化,但不可依赖。
- 中大型数组(≥ 1000 元素):
arraycopy比 for 循环快 2–5 倍 - 底层可能调用
rep movsb或 SIMD 指令,一次性搬内存块 - 避免在循环体内反复调用它处理超小片段;可合并为一次大拷贝
注意浅拷贝语义:对象数组只复制引用
它永远是浅拷贝——对 Object[],复制的是引用地址;对二维数组,第一维拷的是子数组引用,修改子数组内容会影响原数组。
- 一维基本类型数组:安全,互不影响
- 一维对象数组:修改目标数组某元素的属性,源数组对应对象也会变
- 需要深拷贝时,得配合序列化、克隆或手动遍历构造新对象











