Java数组本身固定长度,需通过创建新数组并复制元素模拟动态扩容,常用Arrays.copyOf()或System.arraycopy();可封装工具类维护size并自动扩容,但性能低于预估容量或直接使用ArrayList。

Java 中数组本身是固定长度的,无法真正“动态扩容”,但可以通过创建新数组、复制元素来模拟动态扩容效果。核心思路是:申请更大容量的新数组,把旧数组内容复制过去,再用新数组替换旧引用。
手动实现扩容与复制
最直接的方式是使用 Arrays.copyOf() 或 System.arraycopy() 完成复制:
-
Arrays.copyOf(arr, newLength):返回一个新数组,长度为
newLength,前arr.length个元素来自原数组,超出部分补默认值(如 0、null) - System.arraycopy(src, srcPos, dest, destPos, length):底层高效复制,需确保目标数组已存在且足够大
示例:将 int 数组从长度 3 扩容到 5
int[] arr = {1, 2, 3};
arr = Arrays.copyOf(arr, 5); // {1, 2, 3, 0, 0}
// 或
int[] newArr = new int[5];
System.arraycopy(arr, 0, newArr, 0, arr.length); // 复制前3个元素
arr = newArr;
封装成可复用的动态数组工具类
为避免重复写扩容逻辑,可封装一个简单工具类,维护数组引用和当前大小:
立即学习“Java免费学习笔记(深入)”;
- 定义私有数组字段和 size 记录实际元素数
- 提供
add()方法:检查容量是否足够,不足则扩容(通常 ×1.5 或 +10) - 扩容时用
Arrays.copyOf()创建新数组,再赋值
这样就模拟了类似 ArrayList 的行为,只是不带泛型和线程安全等高级特性。
注意扩容时机与性能开销
频繁扩容会带来明显性能损耗,因为每次都要分配内存+复制数据:
- 建议预估容量,初始化时指定合理大小(如
new int[16]) - 扩容倍数不宜过小(如 ×1.1),否则复制太频繁;也不宜过大(如 ×2),浪费空间
- 若已知最终规模,一次性扩容到位比多次小步扩容更高效
为什么不用 ArrayList?
日常开发中,除非在底层实现容器或有特殊约束(如不能依赖 JDK 集合类),否则应优先使用 ArrayList。它内部正是基于 Object[] 实现动态扩容,已优化了复制策略、扩容比例(1.5 倍)和边界判断,比手写更健壮可靠。


















