arrays.copyof 不提供自动扩容,仅复制并返回新数组;需手动赋值如 arr = arrays.copyof(arr, 10) 才实现逻辑扩容,且对 null 抛 npe;其本质是创建新数组、复制数据、填充默认值,不修改原数组。

Arrays.copyOf 本身不提供自动扩容逻辑,它只是一个“复制工具”——返回一个指定长度的新数组,内容来自原数组。所谓“自动扩容”,是开发者在业务代码中主动调用它,并配合引用更新、容量判断等步骤模拟出来的行为。
它不自动,但可被用来构建扩容流程
Java 数组对象创建后长度固定,无法原地变长。Arrays.copyOf 的作用是:分配一块新内存(连续)、把旧数据搬过去、多出的位置填默认值(0 / null / false)。它不修改原数组,也不感知“是否需要扩容”,只忠实地执行“创建 + 复制”两件事。
- 调用
Arrays.copyOf(arr, 10)不会改变arr的 length,arr仍指向原来的数组对象 - 必须写成
arr = Arrays.copyOf(arr, 10),才完成“逻辑上的扩容” - 如果原数组为
null,该方法直接抛NullPointerException,无空值容错
扩容时的长度决策有讲究
盲目设新长度会导致性能或内存浪费。例如每次只 +1,会引发频繁复制;设成原长 ×2,又可能过度预留。
- ArrayList 内部采用
oldCapacity + (oldCapacity >> 1)(即 1.5 倍),兼顾空间利用率与复制次数 - 推荐策略:
int newLength = Math.max(oldLength + 1, (int)(oldLength * 1.5)) - 若已知后续将追加 N 个元素,可一步到位:
newLength = oldLength + N,避免多次 grow
不同类型数组的复制表现一致,但后果不同
无论 int[] 还是 String[],Arrays.copyOf 都执行浅拷贝:数值类型复制值,引用类型复制地址。
-
int[] a = {1}; int[] b = Arrays.copyOf(a, 2);→b[0]是独立副本,改b[0]不影响a[0] -
String[] x = {"hello"}; String[] y = Arrays.copyOf(x, 2);→x[0]和y[0]指向同一个字符串对象(不可变,安全);但若换成自定义对象数组,修改y[0].field会影响x[0].field - 如需深拷贝,需额外遍历并调用
clone()或构造新实例,Arrays.copyOf 无法替代
和 ArrayList 的关系:它就是底层引擎
ArrayList 的 grow() 方法核心就一行:elementData = Arrays.copyOf(elementData, newCapacity)。ArrayList 封装了容量校验、边界处理、并发提示等逻辑,而 Arrays.copyOf 只负责最干净的“换底座+搬数据”。
- 日常开发中,除非有特殊需求(如 JNI、极致性能、数组语义强约束),否则应优先使用 ArrayList
- 手动用 Arrays.copyOf 扩容,本质是在复现 ArrayList 已经验证过的路径,容易遗漏溢出检查、null 判定、泛型擦除等问题
- 真正关键的不是“怎么扩”,而是“什么时候扩”和“扩多少”——这取决于你的数据增长模式,而非 copyOf 的语法











