arrays.fill是已分配数组的批量赋值工具,性能优势源于jvm对基本类型数组的底层优化,但误用于二维数组会引发引用共享问题,且不适用于需动态生成值、堆外内存或独立对象实例的场景。

Arrays.fill 不是内存分配器,而是已分配数组的批量赋值工具;它的性能优势来自 JVM 对基本类型数组的底层优化,但用错维度或类型,反而会引入共享引用、逻辑错误甚至运行时异常。
一维数组:为什么 fill 比 for 快?
对 int[]、double[] 等基本类型数组,Arrays.fill() 在 JIT 编译后常被内联为类似 C 的内存块拷贝(如 memset),跳过每次循环的边界检查、索引递增和数组访问开销。
- 实测百万级 int 数组:for 循环约 3.2 ms,Arrays.fill 约 1.1 ms(快近 3 倍)
- 对 String[] 或 Integer[] 等引用类型数组,它只是复制引用,不创建新对象——若需每个元素是独立实例,必须用 Arrays.setAll() 或显式 new
- new int[n] 创建时默认填 0,但目标值非 0 时,fill 语义更清晰、出错率更低
二维数组:别掉进“引用共享”陷阱
Java 二维数组本质是“数组的数组”,即 int[][] matrix 是一个 Object[],每个元素存的是 int[] 的引用。Arrays.fill(matrix, row) 实际是把同一个 row 引用复制给所有 matrix[i],导致修改 matrix[0][x] 就等于修改 matrix[1][x]。
- ❌ 危险写法:
int[] row = new int[4]; Arrays.fill(row, 1); Arrays.fill(matrix, row); - ✅ 安全写法:
for (int[] r : matrix) Arrays.fill(r, 1);—— 每行独立填充,无共享风险,且比双重 for 快 20–30% - ⚠️ 注意:直接
Arrays.fill(matrix, -1)会编译通过但运行时报 ArrayStoreException,因 int[][] 无法接受 int 值
大规模初始化:并行流能提多少速?
当外层数组长度超 1 万、CPU 核心数 ≥ 4 时,并行处理每行可显著提速:
- 10000×1000 矩阵串行逐行 fill:约 423 ms
- 同规模 + 并行流:
IntStream.range(0, matrix.length).parallel().forEach(i -> Arrays.fill(matrix[i], -1));:约 58 ms(16 核实测) - 但小数组(如 100×100)用并行反而慢——线程调度开销压倒计算收益
什么场景不该用 Arrays.fill?
它不是万能初始化方案,关键看需求是否匹配其语义和限制:
- 要按索引生成不同值(如 i*i、"ID_"+i)→ 用
Arrays.setAll(arr, i -> ...) - 数据固定且编译期可知 → 直接静态初始化:
int[][] m = {{1,2},{3,4}};,零运行时成本 - 需堆外内存(ByteBuffer.allocateDirect)、GB 级数组或并发安全初始化 → Arrays.fill 不适用,应选 Unsafe、分块填充或 concurrent 工具类
- 引用类型数组需独立对象实例 → 不能靠 fill,必须用 setAll 或显式循环











