关于Arrays.fill方法和Java赋值的底层原理

问题

今天在写leetcode的时候看到了这样一个例子:

StringBuilder[] a = new StringBuilder[5];
Arrays.fill(a, new StringBuilder("asdfg"));
a[0].deleteCharAt(0);
for (StringBuilder s : a) {
    System.out.println(s);
}

和输出

sdfg
sdfg
sdfg
sdfg
sdfg

底下的人解释说是因为fill方法是将Object引用分配给指定的数组中的每个元素,所以当改变数组中其中一个元素时,别的元素也会同时改变,因为他是同一个。

然后我略加思索,敲出了下面的代码:

int b = 1;
int[] a = new int[5];
Arrays.fill(a, b);
b = 2;
System.out.println(Arrays.toString(a));

但是结果却是

[1, 1, 1, 1, 1]

原理

为什么就没发改变了呢?这就牵扯到一个有意思的东西了:
1、如果变量是基本数据类型,此时赋值的是变量所保存的数据值.
于是
int a1=1;int a2=a1是两个内存空间中有两个1,他们相等.
2、如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值,于是

StringBuilder a1 = new StringBuilder();
StringBuilder a2 = new StringBuilder();
a2=a1

是两个内存空间现在指向了同一个地址,他们的内容是同一个内容。

回到上述的问题中,为什么第一段代码改变了而第二段代码没有改变呢?
我认为根本就不是那个人说的“因为fill方法是将引用分配给数组中的每一个元素”,而是因为fill方法的本质相当于“=”号,当你使用Arrays.fill(a, new StringBuilder("asdfg"));时,“=”号将此对象的地址赋值给了a数组中的所有元素。而当你使用Arrays.fill(a, b);时,“=”号只是将b的值赋值给了a数组中的所有元素。所以当你a[0].deleteCharAt(0);时,地址中的值发生了改变,所以所有元素都发生了改变。而当你改变b的值时,a自然不会变。

参考

链接: Java核心技术系列之华东师范大学Java核心技术第四章对象与类,话谈Java中的赋值与变量交换底层原理、构造函数、信息隐藏、this

问题原文:
链接: 在java中的StringBuilder数组中操作StringBuilder

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`Arrays.fill()`是Java中的一个静态方法,用于将指定数组中的每个元素都设置为指定的值。它接受三个参数:数组、起始索引和结束索引(不包括)以及要设置的值。 语法: ``` public static void fill(int[] a, int val) public static void fill(int[] a, int from, int to, int val) public static void fill(boolean[] a, boolean val) public static void fill(boolean[] a, int from, int to, boolean val) public static void fill(byte[] a, byte val) public static void fill(byte[] a, int from, int to, byte val) public static void fill(char[] a, char val) public static void fill(char[] a, int from, int to, char val) public static void fill(double[] a, double val) public static void fill(double[] a, int from, int to, double val) public static void fill(float[] a, float val) public static void fill(float[] a, int from, int to, float val) public static void fill(long[] a, long val) public static void fill(long[] a, int from, int to, long val) public static void fill(short[] a, short val) public static void fill(short[] a, int from, int to, short val) ``` 其中,`a`是要填充的数组,`val`是要填充的值,`from`是起始索引,`to`是结束索引(不包括)。 示例: ``` int[] arr = new int[5]; Arrays.fill(arr, 5); System.out.println(Arrays.toString(arr)); // 输出 [5, 5, 5, 5, 5] int[] arr2 = new int[10]; Arrays.fill(arr2, 2, 7, 8); System.out.println(Arrays.toString(arr2)); // 输出 [0, 0, 8, 8, 8, 8, 2, 2, 2, 2] ``` 在第一个示例中,我们将一个长度为5的整型数组填充为值5。在第二个示例中,我们将一个长度为10的整型数组中从索引2到索引7(不包括)的元素填充为值8。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值