arrays.copyof不支持动态扩容,仅创建新数组并复制元素;必须手动赋值引用、管理容量策略(如1.5倍增长),且为浅拷贝——基本类型安全,引用类型共享对象;多数场景应优先使用arraylist。

Arrays.copyOf 本身不支持动态数组构建,它只提供“复制+重定长”的能力;所谓“动态构建”,必须靠你主动调用、赋值引用、管理容量三步协同完成。
核心逻辑:复制生成新数组,再替换引用
Java 数组长度不可变,扩容不是原地伸缩,而是“弃旧建新”。Arrays.copyOf 的作用就是高效创建这个“新”——它底层调用 System.arraycopy,保证数据复制安全且快速。但关键一步:你得手动把变量指向这个新数组。
- 错误写法:
Arrays.copyOf(arr, 10);→ 返回值被丢弃,arr 仍是原数组 - 正确写法:
arr = Arrays.copyOf(arr, 10);→ 引用更新,后续操作落在新数组上 - 若 arr 是方法参数且未返回或重新赋值,扩容对外不可见
容量增长策略要合理,不能硬编码
盲目每次 +1 或 ×2 容易引发频繁复制(性能差)或内存浪费(开太大)。参考 ArrayList 的成熟做法:
- 推荐公式:
int newLength = Math.max(oldLength + 1, (int)(oldLength * 1.5)); - 如果已知后续要加 N 个元素,可一步到位:
Arrays.copyOf(arr, arr.length + N) - 新长度 ≤ 原长度时,copyOf 自动截断;> 原长度时,末尾补默认值(int 补 0,String 补 null)
类型安全与浅拷贝特性必须清楚
泛型数组(如 String[])要用带类型参数的重载,避免用 Object[] 版本导致类型擦除;同时牢记它是浅拷贝:
- 基本类型数组(int[]、boolean[]):拷贝数值,安全无副作用
- 引用类型数组(Person[]、String[]):拷贝的是地址,新旧数组共享同一对象实例
- 若需隔离修改(深拷贝),copyOf 不管用,得遍历调用 clone() 或构造新对象
多数场景其实该用 ArrayList 而非手写扩容
自己封装 copyOf 扩容,本质是在重复造轮子。ArrayList 内部正是基于 Arrays.copyOf 实现 grow(),还做了容量校验、批量优化、API 封装等。
- 如果你只需要增删查、保持顺序、自动扩容 → 直接用 ArrayList,add() 即可
- 只有在特殊需求下才需手动控制数组:如 JNI 交互要求原始数组、高性能计算规避对象头、或封装底层容器
- 真正目标不是“扩容”,而是支撑后续业务读写——选对工具比写对代码更重要











