system.arraycopy是大数组分页拷贝的首选,因其调用jvm底层c实现、跳过java层校验、按内存块批量搬运,性能达for循环的3–5倍,且不创建新数组,契合分页需求。

大数组分页拷贝的核心在于避免内存暴增和提升效率,System.arraycopy 是 Java 中最轻量、最高效的原生数组复制工具,它直接调用 JVM 底层 C 实现,比循环赋值快得多,也比 Arrays.copyOf 更可控。
为什么选 System.arraycopy 而不是 for 循环?
for 循环逐个赋值在小数组上问题不大,但面对百万级元素时,JVM 的边界检查、类型校验和解释执行开销会明显拖慢速度。而 System.arraycopy 是本地方法(native),跳过 Java 层校验,按内存块批量搬运,实测性能通常是 for 循环的 3–5 倍。更重要的是,它不创建新数组——你得自己 new 目标数组,这恰好契合分页场景中“每次只处理一页”的需求。
分页拷贝的关键参数怎么算?
分页本质是把源数组切成若干段,每段长度为 page size(如 1000),最后一段可能不足。关键是要算准三个数:起始索引(from)、目标起始位置(to)、拷贝长度(length)。常用逻辑如下:
- 当前页起始下标 = pageIndex × pageSize
- 当前页实际长度 = Math.min(pageSize, src.length - pageIndex × pageSize)
- 目标数组需提前 new 出,长度等于该页实际长度(或固定 pageSize,留空位)
一个安全可用的分页拷贝示例
以下是一个带边界防护的通用方法,适用于 int[]、String[] 等任意一维引用/基本类型数组:
public static <t> T[] copyPage(T[] src, int pageIndex, int pageSize, Class<t> type) {
if (src == null || pageIndex = src.length) return (T[]) Array.newInstance(type, 0);
int length = Math.min(pageSize, src.length - fromIndex);
T[] dest = (T[]) Array.newInstance(type, length);
System.arraycopy(src, fromIndex, dest, 0, length);
return dest;
}</t></t>
注意:基本类型数组(如 int[])不能用泛型擦除方式处理,需单独重载方法,例如为 int[] 写专用版本,避免装箱开销。
常见陷阱与规避建议
使用 System.arraycopy 分页时容易踩坑,几个高频问题要提前防住:
- 数组越界异常:传入的 fromIndex 或 length 超出源数组范围,务必先做 Math.min 和 >=0 判断
- 目标数组太小:dest 数组长度小于指定 length,会抛 ArrayStoreException(引用类型)或 IndexOutOfBoundsException(基本类型)
- 类型不匹配:src 是 String[],dest 是 Object[] 可以;但反过来(Object[] → String[])会失败,因为运行时类型检查通不过
- 并发修改风险:若源数组正被其他线程写入,拷贝结果可能不一致,必要时加锁或使用不可变副本
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











