System.arraycopy本身不扩容,需先创建新数组再复制;ArrayList底层扩容即采用此逻辑,推荐优先使用Arrays.copyOf。

Java 中 System.arraycopy 本身不直接“扩容”,而是高效复制数组内容;真正的扩容需先创建新数组,再用 arraycopy 搬运旧数据。这是 ArrayList 等集合底层扩容的核心逻辑。
基础扩容模板(通用整型数组)
以下是最简明、可复用的扩容代码结构:
- 声明原数组和目标长度(如扩大为原长度的 1.5 倍)
- 用
new int[newLength]创建新数组 - 调用
System.arraycopy(src, 0, dest, 0, src.length)完整复制 - 将引用指向新数组(注意:原数组若无其他引用,会被 GC)
int[] arr = {1, 2, 3};
int newLength = (int) (arr.length * 1.5); // 例如扩到 4 或 5
int[] newArr = new int[newLength];
System.arraycopy(arr, 0, newArr, 0, arr.length);
arr = newArr; // 关键:更新引用
封装成可复用的扩容方法(泛型限制下用 Object)
Java 数组不支持泛型擦除后的安全扩容,但可用 Object[] + 类型转换模拟(类似 ArrayList):
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 传入原数组和新容量,返回新数组引用
- 用
Array.newInstance或强制类型转换处理不同元素类型 - 实际项目中更推荐使用
Arrays.copyOf(它内部就调用arraycopy)
public static int[] grow(int[] original, int minCapacity) {
int oldLength = original.length;
if (minCapacity <= oldLength) return original;
int newLength = Math.max(oldLength + (oldLength >> 1), minCapacity);
int[] grown = new int[newLength];
System.arraycopy(original, 0, grown, 0, oldLength);
return grown;
}
关键细节与避坑提醒
写错参数极易导致空指针、越界或静默丢数据:
立即学习“Java免费学习笔记(深入)”;
- srcPos 和 destPos 通常为 0,但若只复制后半段,需校准起始偏移
-
length 参数必须 ≤ src.length 且 ≤ (dest.length − destPos),否则抛
ArrayStoreException或IndexOutOfBoundsException - 源数组和目标数组**类型需兼容**(如不能把
String[]复制到Integer[]) - 对基本类型数组,无需担心对象引用问题;对引用类型,复制的是引用值,不是深拷贝
替代方案建议:优先用 Arrays.copyOf
除非有极致性能要求或学习目的,日常开发推荐更简洁安全的写法:
int[] newArr = Arrays.copyOf(arr, newLength);String[] newArr = Arrays.copyOf(original, newLength, String[].class);- 其底层就是封装好的
arraycopy,且自动处理 null、负长度等边界

















