Arrays.fill对基本类型填充独立值副本,修改互不影响;对引用类型填充同一对象引用,修改会相互影响,需用循环创建独立对象。

Arrays.fill 在 Java 中用于将数组的指定范围(或整个数组)填充为指定值。它对基本类型数组和引用类型数组的处理机制本质相同,但语义效果和潜在风险有明显差异,核心在于“值”的含义不同:基本类型填的是真实数据副本,引用类型填的是同一对象的多个引用。
对基本类型数组:安全、独立、无副作用
填充时,每个数组元素都被赋予该基本类型的独立副本。修改其中一个元素,不会影响其他元素。
- 例如:int[] arr = new int[3]; Arrays.fill(arr, 42); → arr 变为 {42, 42, 42}
- 后续执行 arr[0] = 100; 只改变第一个元素,其余仍为 42
- 所有元素在内存中是完全独立的整数值,不存在共享问题
对引用类型数组:填充的是同一引用,非新对象
Arrays.fill 并不创建新对象,只是把传入的引用值(即对象地址)复制到每个数组位置。结果是所有元素指向同一个对象实例。
- 例如:List<String>[] lists = new ArrayList[3]; Arrays.fill(lists, new ArrayList<>());
- 此时 lists[0]、lists[1]、lists[2] 全部引用同一个 ArrayList 实例
- 执行 lists[0].add("a"); 后,lists[1].size() 也会是 1 —— 因为操作的是同一个列表
常见误用与规避建议
开发者常误以为 Arrays.fill(objArray, new SomeClass()) 会为每个位置创建独立对象,实际并非如此。
立即学习“Java免费学习笔记(深入)”;
- 若需每个元素是独立对象,应使用循环显式构造:for (int i = 0; i
- 对不可变引用类型(如 String、Integer),因对象本身不可变,填充后行为“看似安全”,但仍是共享引用,仅无运行时副作用
- 对可变对象(如 ArrayList、自定义 POJO),务必警惕多处修改引发的意外状态共享
底层实现统一,语义差异源于类型本质
查看 Arrays.fill 源码可见,无论基本类型还是引用类型,方法内部都是通过循环赋值实现(如 a[i] = val)。区别不在 fill 方法本身,而在于:
– 基本类型变量存储值本身;
– 引用类型变量存储的是对象地址。
因此,“填同一个值”在两种场景下自然导致截然不同的内存布局与行为表现。










