arrays.fill是java中为已创建数组批量设同值最简洁、语义最清晰的方式,支持一维全填/区间填充(左闭右开)、二维逐行调用防引用共享、对象数组仅填不可变实例或null,不分配内存、不保证线程安全。

Arrays.fill 是 Java 中为已创建数组批量设值最简洁、语义最清晰的方式,不分配新内存、不引入依赖,一行代码完成初始化或重置。它不是万能的构造工具,但对“同值填充”这个明确任务,就是最优解。
一维数组:全填或分段,按需“上色”
新建数组后快速赋予业务含义的默认值,比手动循环更安全,也比依赖默认初始化(如 int[] 默认为 0)更具可读性:
- 全数组填充:如 int[] data = new int[1000]; Arrays.fill(data, -1); 表示“未计算”状态,比默认 0 更易区分有效值
- 布尔开关初始化:boolean[] visited = new boolean[500]; Arrays.fill(visited, false); 显式表达初始未访问意图
- 字符串占位:String[] names = new String[10]; Arrays.fill(names, "N/A"); 避免后续判空时触发 NullPointerException
- 区间精准填充:如滑动窗口重置、DP 数组预设无效段——Arrays.fill(dp, 0, k, Integer.MAX_VALUE); 或 Arrays.fill(cache, offset, offset + len, 0);
注意:区间是左闭右开,fill(arr, i, j, v) 影响索引 i 到 j−1;fromIndex ≥ 0、toIndex ≤ arr.length,否则抛 ArrayIndexOutOfBoundsException
二维数组:逐行调用,避免引用共享
Java 的二维数组本质是“一维引用数组”,每个元素指向一个独立的一维数组。Arrays.fill 对它作用的是引用层,不是数据层——填进去的是地址,不是数字:
- 错误写法:int[][] grid = new int[5][5]; Arrays.fill(grid, 9); 编译失败,因为 9 无法赋给 int[] 类型
- 更危险的写法:int[] row = new int[5]; Arrays.fill(row, 9); Arrays.fill(grid, row); 表面成功,实则所有行共用同一块内存,改 grid[0][0] 就等于改了所有 grid[i][0]
- 正确做法:用循环逐行填充,确保每行都是独立实例
for (int[] r : matrix) Arrays.fill(r, 0);
或按需差异化赋值:for (int i = 0; i
对象数组:填不可变值才安全
Arrays.fill 填的是引用,不是新对象。是否安全,取决于你填的对象是否可变:
- 安全场景:填 null、字符串字面量("N/A")、包装类常量(Integer.valueOf(0)、Boolean.TRUE),它们不可变或复用常量池,无共享风险
- 危险场景:List
[] lists = new ArrayList[3]; Arrays.fill(lists, new ArrayList()); → 三个索引都指向同一个 ArrayList,add 元素会互相干扰 - 替代方案:需要独立实例时,用循环或 Arrays.setAll
Arrays.setAll(people, i -> new Person("user" + i, i * 20));
语义更明确,天然规避共享问题
性能与边界:快且稳的关键细节
Arrays.fill 底层是 for 循环,性能和手写循环几乎无差别,但它胜在语义清晰。真正影响效率和安全的是使用方式:
- JVM 对基本类型数组(如 int、boolean)有 intrinsic 优化,实测比普通循环快近 3 倍
- 区间填充务必校验:fromIndex ≥ 0、toIndex ≤ arr.length、fromIndex ≤ toIndex,否则运行时报异常
- 填 Boolean[] 时,直接传 true 或 false 安全(复用常量),但绝不能用 new Boolean(true) —— 这只创建一次实例,所有位置共享引用
- 填 boolean[] 和 Boolean[] 有本质区别:boolean[] 填原始值、无装箱开销;Boolean[] 填引用、支持 null,但需额外判空
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











