java中数组拷贝最常用且高效的方式是system.arraycopy,它底层调用native方法,性能优于循环赋值和arrays.copyof,但需严格校验参数一致性以避免arraystoreexception或indexoutofboundsexception。

Java 中数组拷贝最常用且高效的方式是 System.arraycopy,它底层调用的是本地方法(native),性能远超循环赋值或 Arrays.copyOf 封装。但参数写错、边界越界、类型不匹配等问题极易引发运行时异常,实际开发中需格外谨慎。
核心参数含义与常见误用
该方法签名如下:
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
五个参数必须同时满足逻辑一致性,否则抛出 ArrayStoreException 或 IndexOutOfBoundsException:
-
src 和 dest 类型需兼容:若 src 是
String[],dest 必须是String[]或其父类型数组(如Object[]),但不能是Integer[];基本类型数组之间不可互拷(int[]不能拷到long[]) -
srcPos + length ≤ src.length:超出源数组范围会触发
IndexOutOfBoundsException - destPos + length ≤ dest.length:目标数组空间不足同样报错
-
length 不能为负数:哪怕 src/dest 非 null,负长度直接抛
IllegalArgumentException
安全调用的三步检查法
在调用前加入轻量校验,可避免多数运行时崩溃:
- 判空:先确认
src != null && dest != null,否则 NPE - 算边界:用
Math.min(src.length - srcPos, dest.length - destPos)动态截取最大合法length,防止越界 - 控方向:若需“倒序拷贝”或“重叠拷贝”(如数组内移动),务必用
srcPos 判断是否应从后往前复制,否则数据被覆盖
替代方案对比与选型建议
并非所有场景都适合 System.arraycopy:
- 浅拷贝需求明确、性能敏感(如高频日志缓冲区刷新)→ 优先用
arraycopy - 需要新数组且长度固定 →
Arrays.copyOf(src, newLength)更简洁,内部其实也调用arraycopy - 涉及对象数组深层复制 →
arraycopy仅复制引用,需配合序列化或手动 clone - 泛型集合转数组 → 直接用
list.toArray(new Type[list.size()]),避免类型擦除导致的ArrayStoreException
异常捕获与日志增强技巧
生产环境不应裸 throw 异常,建议包装上下文信息:
- 捕获
IndexOutOfBoundsException后,记录src.length、srcPos、length、dest.length、destPos具体值,快速定位哪一维越界 - 对
ArrayStoreException,打印src.getClass().getComponentType()和dest.getClass().getComponentType(),比堆栈更直观 - 单元测试中用
@Test(expected = IndexOutOfBoundsException.class)覆盖边界 case,比如srcPos = src.length或length = 1但srcPos = src.length
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











