system.arraycopy在重叠拷贝时自动保障数据正确性,等效于c的memmove:destpos>srcpos时倒序拷贝防覆盖,destpos

System.arraycopy 在源数组与目标数组重叠时能自动保障数据正确性,根本不需要你手动判断方向或拆分逻辑——它底层的行为逻辑等同于 C 的 memmove。
重叠拷贝的方向由 srcPos 和 destPos 的大小关系决定
JVM 会根据起始位置的相对关系,自动选择复制顺序:
- 当 destPos > srcPos(目标起始在源起始右边),属于“前向重叠”,自动从高索引往低索引倒序拷贝,防止未读数据被覆盖;
- 当 destPos (目标起始在源起始左边),属于“后向重叠”,自动从低索引往高索引正序拷贝,保证已读数据不被干扰;
- 当 destPos == srcPos,即原地复制或零长度操作,直接跳过搬运,不产生副作用。
典型安全场景示例
例如对 int[] arr = {1,2,3,4,5} 执行左移一位:
System.arraycopy(arr, 1, arr, 0, 4);
这里 destPos=0 ,属后向重叠,JVM 正序执行:先拷 <code>arr[1]→arr[0],再 arr[2]→arr[1]……最终得到 {2,3,4,5,5},符合预期。
再如右移两位:System.arraycopy(arr, 0, arr, 2, 3),因 destPos=2 > srcPos=0,自动倒序拷贝,确保 arr[2] 不被提前覆盖。
真正要警惕的不是重叠,而是参数非法
重叠本身不会出错,但以下情况会立即抛异常:
-
srcPos + length > src.length或destPos + length > dest.length→ArrayIndexOutOfBoundsException; - 源数组与目标数组类型不兼容(如
String[]拷到Integer[])→ArrayStoreException; - 任一数组为
null→NullPointerException。
这些校验都在拷贝开始前完成,不会让错误数据悄悄写入。
不要手动加临时数组,那是画蛇添足
有人担心重叠危险,于是先复制到临时数组再搬回——这反而多一次内存分配和两次拷贝,性能下降且无必要。
System.arraycopy 的重叠处理是 JVM 级别保障,比手写循环更可靠(不易方向写反、边界算错),还享有向量化加速优势。只要参数合法,结果一定语义正确。











