填基本类型字面量或null最安全,因避免共享引用;填可变对象(如new arraylist())会导致所有元素指向同一实例,引发意外修改。

Arrays.fill 填什么值最安全
填基本类型字面量或 null 是最稳妥的,别填可变对象引用。比如用 Arrays.fill(arr, new ArrayList()) 看似方便,实际会让所有数组元素指向同一个 ArrayList 实例——改一个,全跟着变。
常见错误现象:arr[0].add("a"); System.out.println(arr[1].size()); // 输出 1
- 填
0、false、null没问题 - 填新对象(如
new Object())只适合一次性初始化且后续不修改引用的场景 - 若需每个元素是独立对象,必须用循环手动创建
fill 的重载方法怎么选参数范围
关键看是不是要填整个数组。Arrays.fill(Object[], Object) 填全部;Arrays.fill(Object[], int, int, Object) 填子区间——注意第二个参数是起始索引(含),第三个是结束索引(不含),这点和 substring 一致,但和 Python 切片容易混淆。
使用场景:初始化二维数组某一行、跳过已设置的头几个元素、批量重置部分缓存位
立即学习“Java免费学习笔记(深入)”;
- 越界会直接抛
ArrayIndexOutOfBoundsException,不是静默失败 - 起始索引可以等于数组长度(此时不填任何元素),但不能超过
- 结束索引小于起始索引时,方法不报错,但也不执行填充
为什么 fill 后 == 比较有时成立,有时不成立
这取决于填的是什么值。基本类型数组(如 int[])填数值后,== 比较值当然成立;但引用类型数组(如 String[])填字符串字面量时,因为字符串常量池,arr[0] == arr[1] 可能为 true;填 new String("x") 就一定为 false。
性能影响:对引用数组,fill 只是复制引用,不触发对象创建或 GC,非常快;但若误以为填了新对象而忽略深拷贝需求,后续逻辑就容易出错。
int[] a = new int[3]; Arrays.fill(a, 42); a[0] == a[1] // trueString[] b = new String[3]; Arrays.fill(b, "hi"); b[0] == b[1] // true(常量池)Arrays.fill(b, new String("hi")); b[0] == b[1] // false
替代 fill 的常见误操作
有人用 Arrays.setAll 或循环赋值来“更灵活”,但其实多数时候是画蛇添足。只要目标是统一值,Arrays.fill 是语义最清晰、JVM 也最可能做底层优化的方式。
容易踩的坑:在泛型集合(如 List<t></t>)上想“类比 fill”而调用 list.replaceAll(x -> value),这不仅慢,还要求 list 支持随机访问;真要批量设值,不如先清空再 addAll(Collections.nCopies(n, value))。
-
Arrays.fill是原地操作,无返回值,别试图链式调用 - 对
boolean[]填true/false安全;但别用Arrays.fill(arr, Boolean.TRUE),虽然能编译,但装箱后是Boolean对象,和基本类型语义已不同 - Android 低版本(API fill 的 range 重载,需自行校验
真正要注意的,是填的到底是不是你“以为的那个东西”——尤其是引用类型数组里那个被反复复制的指针。










