System.arraycopy不能扩容数组,因为它只复制元素而不改变数组长度;真正的扩容需三步:创建新数组、用arraycopy复制数据、更新引用;实际开发中应优先使用ArrayList等集合类。

System.arraycopy 本身并不扩容数组,它只是把数据从一个数组复制到另一个数组。Java 中数组是固定长度的,无法真正“扩容”,所谓“扩容”其实是创建一个更大的新数组,再用 arraycopy 把旧数据搬过去。
为什么 arraycopy 不能直接扩容?
因为数组对象在内存中分配后,其长度就不可变。System.arraycopy 的签名是:
它不修改任何数组的长度,只负责按索引搬运元素。目标数组(dest)必须已存在且足够大,否则会抛 ArrayIndexOutOfBoundsException 或 NullPointerException。
模拟扩容的典型做法
要实现“扩容效果”,需三步:申请新数组 → 复制旧数据 → 替换引用。例如将 int 数组扩容为原长的 1.5 倍:
立即学习“Java免费学习笔记(深入)”;
- 计算新容量:
int newLength = oldArray.length + (oldArray.length >> 1); - 创建新数组:
int[] newArray = new int[newLength]; - 复制数据:
System.arraycopy(oldArray, 0, newArray, 0, oldArray.length); - 更新引用:
oldArray = newArray;(注意:这仅在局部变量或字段可重新赋值时有效)
实际开发中更推荐的方式
手动管理数组扩容容易出错,建议优先使用封装好的集合类:
-
ArrayList内部正是用类似上述逻辑自动扩容(默认扩容 1.5 倍),调用add()时无需关心底层 - 如果必须用原始数组(如高性能场景),可封装工具方法,避免重复写复制逻辑
- 注意:扩容后原数组未被修改,所有指向它的其他引用仍指向旧数组,这点常被忽略
不复杂但容易忽略的是:扩容本质是“换数组”,不是“改数组”。arraycopy 是搬砖的工人,而盖新楼(new 数组)和拆旧楼(丢弃旧引用)得你来安排。


















