关于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
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值