system.arraycopy本身不扩容,仅高效搬运数据;高性能扩容需嵌入“判断容量不足→创建新数组→搬运有效元素”三步流程,搬运长度严格为size而非数组length。

System.arraycopy 本身不扩容,只负责高效搬运数据;真正实现高性能扩容,关键在于把它嵌入一个可控、轻量、可复用的三步流程中:判断容量不足 → 创建新数组 → 用 arraycopy 搬运有效元素。
扩容必须分两步:分配 + 搬运
Java 数组长度固定,无法“就地变长”。每次扩容本质是:
- 计算新容量(例如原长 × 1.5,且至少为 size + 1)
- 用 new int[newLength] 或 new Object[newLength] 分配一块新的连续内存
- 调用 System.arraycopy(src, 0, dest, 0, size) 把当前有效的 size 个元素一次性搬过去
- 最后更新引用:array = newArr,并同步维护 size/capacity 状态
搬运时只拷有效数据,长度必须是 size
常见错误是写成 arraycopy(..., newArr.length),这会把默认值(如 0、null)也复制进去,污染逻辑。正确做法是:
- 源起始位置始终为 0
- 目标起始位置也从 0 开始(追加场景)
- 拷贝长度严格等于当前已存元素数 size,不是原数组 length,更不是新数组 length
- 例如:原数组有 7 个元素(size = 7),即使 length 是 10,也只拷前 7 个
推荐扩容策略:1.5 倍增长 + 最小保障
避免频繁扩容和内存浪费,建议采用类似 ArrayList 的策略:
- 新容量 = Math.max(oldCap + 1, (int)(oldCap * 1.5))
- 初始容量设为 8 或 16,防止小数组反复扩
- 提供 ensureCapacity(int min) 方法,供调用方预判,避开临界点性能毛刺
- 对中等规模数据,1.2~1.5 倍比固定 ×2 更省内存
封装成方法更安全、易复用
直接裸写 arraycopy 容易出错。封装后既隐藏细节,又便于统一控制:
- 基础版(int[]):public static int[] grow(int[] src, int minCapacity),内部完成计算、创建、搬运、返回
- 泛型友好版:用 Object[] 存储,get 时强转;或构造时传 Class
,用 Array.newInstance(clazz, newCap) 创建类型化数组 - 日常开发可直接用 Arrays.copyOf(arr, newLength),它底层就是封装好的 arraycopy,还自带空值/负长防护











