Arrays.fill仅支持浅填充,对对象数组会共享同一实例,导致修改同步;填充二维数组或需独立对象时应改用循环或Arrays.setAll。

Arrays.fill 不能直接填充含对象引用的复杂结构数组(比如二维数组、对象数组),它只对基本类型数组或引用数组做“浅填充”——即把每个元素设为指定引用值,而非深拷贝或构造新对象。
理解 Arrays.fill 的“浅填充”本质
对对象数组调用 fill,实际是把数组每个槽位都指向同一个对象实例。修改任一元素的属性,其他位置也会同步变化,因为它们共享同一内存地址。
- 例如:String[] arr = new String[3]; Arrays.fill(arr, "hello"); —— 安全,String 不可变
- 但:List
[] lists = new ArrayList[3]; Arrays.fill(lists, new ArrayList()); —— 危险!三个索引共用一个 ArrayList 实例
填充二维数组:避免共享引用
二维数组本质是一维数组,其元素是“一维数组引用”。用 fill 填充只会让所有行指向同一子数组,导致数据污染。
- 错误写法:int[][] grid = new int[3][]; Arrays.fill(grid, new int[4]); → 所有行都是同一数组
- 正确做法:用循环逐行初始化:for (int i = 0; i
- 也可用 Stream: IntStream.range(0, grid.length).forEach(i -> grid[i] = new int[4]);
填充对象数组:需手动创建独立实例
若要每个位置持有不同对象(如 Person、DTO),必须显式构造,不能依赖 fill。
立即学习“Java免费学习笔记(深入)”;
- 不推荐:Person[] people = new Person[5]; Arrays.fill(people, new Person("default", 0));
- 推荐:for (int i = 0; i
- 或使用 Arrays.setAll:Arrays.setAll(people, i -> new Person("user" + i, i * 20));(更函数式,语义清晰)
替代方案:Arrays.setAll 更适合对象初始化
setAll 接收 IntUnaryOperator 或 IntFunction,按索引生成独立对象,天然规避共享问题,语义也更明确。
- 填充整型数组:int[] nums = new int[10]; Arrays.setAll(nums, i -> i * i);
- 填充对象数组:LocalDateTime[] times = new LocalDateTime[7]; Arrays.setAll(times, i -> LocalDateTime.now().plusDays(i));
- 比 fill + 循环更简洁,且不易出错


















