Arrays.fill()对对象数组只做浅拷贝,所有元素指向同一引用;基本类型数组安全;需注意索引左闭右开、越界风险;初始化新数组或生成计算值时应选构造或Stream替代;大数组fill()性能更优。

Arrays.fill() 为什么填不满对象数组?
它只做浅拷贝,对引用类型数组,其实是把同一个引用复制到每个位置。如果你用 Arrays.fill(arr, new ArrayList()),结果是所有元素都指向同一个 ArrayList 实例——改一个,全跟着变。
- 基本类型数组(
int[]、boolean[])完全安全,填的是真实值 - 对象数组(
String[]、List[])填的是引用,不是新对象 - 真要初始化对象数组,得用循环或
Stream.generate()配合toArray()
fill() 的起始/结束索引容易越界
第三个和第四个参数是左闭右开区间:fill(array, fromIndex, toIndex, value)。常见错误是把 toIndex 写成数组长度加一,或者混淆下标从 0 开始——直接抛 ArrayIndexOutOfBoundsException。
-
fromIndex可以为 0,但不能为负;toIndex最大只能是array.length - 当
fromIndex == toIndex时,什么也不做,不报错 - 如果只填部分元素,务必检查
toIndex <= array.length,别靠“感觉”写数字
替代方案:什么时候不该用 fill()?
想初始化一个全是默认值的新数组?fill() 得先创建再填,多一次操作。不如直接用构造方式更干净。
- 新建
int[10]默认就是 0,不用fill() - 新建
Boolean[5]默认是null,若要全填false,才需要fill() - 批量生成带计算逻辑的值(比如平方数、UUID),用
IntStream.range().mapToObj()更合适
性能差异:fill() vs 手写 for 循环
JVM 对 Arrays.fill() 做了底层优化(比如用内存块拷贝代替逐个赋值),尤其在大数组上比普通 for 快不少。但小数组(
立即学习“Java免费学习笔记(深入)”;
- 对
byte[]和int[],HotSpot 会走 intrinsic 优化路径 - 对象数组不会做内存拷贝,仍是逐引用赋值,性能接近手写循环
- 如果循环体里有分支判断或方法调用,
fill()无法替代——它只干一件事:统一赋值
最常被忽略的是对象数组的语义陷阱:看起来填了十个空列表,实际只有一个。调试时看到数据莫名联动,八成栽在这儿。









