arrays.fill() 初始化对象数组不安全,因只创建一个实例并重复引用;所有元素指向同一对象,修改任一元素会影响全部;应使用for循环或stream生成独立对象。

Arrays.fill() 不能安全地用于快速初始化大型对象数组——它会把同一个对象实例的引用复制到每个位置,所有元素共享同一对象,后续修改任一元素都会影响全部。
为什么 fill 对象数组有风险
调用 Arrays.fill(objArray, new MyObj()) 看似创建了新对象,但实际只执行了一次构造;该对象被赋值给数组所有索引,导致所有元素指向内存中同一个实例。例如:
-
StringBuilder[] arr = new StringBuilder[1000];
Arrays.fill(arr, new StringBuilder("init")); → 全部 1000 个位置都引用同一个 StringBuilder - 执行 arr[0].append("more") 后,arr[1]、arr[999] 的内容也同步改变
真正安全的初始化方式
必须为每个位置单独创建独立对象。推荐以下两种清晰、可控的做法:
-
传统 for 循环(最直观,无兼容性问题):
for (int i = 0; i arr[i] = new MyObj();
} -
Stream.generate(适合 Java 8+,语义明确):
MyObj[] arr = Stream.generate(MyObj::new)
.limit(1000)
.toArray(MyObj[]::new);
如果坚持用 fill,只能用于“不可变”或“只读”场景
仅当确认对象不会被修改(如字符串字面量、Integer 常量、自定义不可变类),才可考虑 fill:
-
String[] names = new String[5000];
Arrays.fill(names, "N/A"); → 安全,String 不可变 -
Integer[] codes = new Integer[1000];
Arrays.fill(codes, 0); → 安全,自动装箱的 Integer 是不可变对象
二维对象数组更需警惕
对 MyObj[][] matrix 调用 Arrays.fill(matrix, new MyObj()),结果是所有行引用同一个对象,不是每行一个对象——更不是每个单元格一个对象。正确做法仍是逐层构造:
- for (MyObj[] row : matrix) {
for (int j = 0; j row[j] = new MyObj();
}
}











