循环外创建对象,内部赋值调用,导致数据出现相同

如下情况:

public static void main(String args[]) throws Exception {
   UserInfo u = new UserInfo();
   u.setUserName("a");
   //这里需要处理user对象数据
   test1(u);//假设后面还有其他数据需要处理,需要传给其他方法
 }
 
 static void test1(UserInfo u){
        //对象只能由参数传递
        List<UserInfo> list = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            u.setPhone("a"+i);
            list.add(u);
        }
        for (UserInfo a:list) {
            System.out.println(a.getPhone());
        }
    }

理论上,我们是想要循环的时候添加不同的值到list,然后输出a0 a1 a2
但实际上输出的却是 a2 a2 a2

a2
a2
a2

那么,造成这种现象的原因是什么呢?
这里第一时间想到的肯定是覆盖,那么是什么形式的覆盖呢?

  1. 首先,我们知道new出来的对象是在堆中开辟了一个空间,然后在栈中关联起来地址值

  2. 其次,我们看看ArrayList的底层结构,其实就是一个Object类型的数组

  3. 那么问题就明白了,add方法也就是将地址u存储到了一个数组中,我们访问集合中的数据,其实也是读取这个数组中地址所指向的值

  4. list保存的是对象地址值,而栈中的地址值一直没有变,setPhone()操作只是引用对象地址值找到该对象的堆空间,并改变phone的值,当最后一次循环结束,phone的值为a2,所以list.add的操作保存的其实是3个地址值相同的u

解决方案1

既然外部new对象是相同的地址值,那么就在内部new对象

for (int i = 0; i < 3; i++) {
	  UserInfo u = new UserInfo();
      u.setPhone("a"+i);
      list.add(u);
    }

解决方案2

当然,之前问题也提到过,对象要处理数据的场景太多,有些需要在循环外,然后在循环内调用,此时同样可以新建一个对象,使用BeanUtils.copyProperties工具传递

static void test1(UserInfo u){
        //对象只能由参数传递
        List<UserInfo> list = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            UserInfo info = new UserInfo();
            u.setPhone("a"+i);
            BeanUtils.copyProperties(u,info);
            list.add(info);
        }
        for (UserInfo a:list) {
            System.out.println(a.getPhone());
        }
    }

输出

a0
a1
a2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值