改动两次对象的值,再往List中添加两次,结果List显示有两个对象,但两个对象的值相等。这个错误犯了两次,记录下来警醒自己也提示别人。
把问题抽象成一个简单的代码:
@RequestMapping("/user")
public RestResult user(){
List<User> userList = new ArrayList<>();
User user = new User();
user.setId("1");
List<String> nameList = new ArrayList<>();
nameList.add("aaa");
nameList.add("bbb");
for (String s:nameList){
user.setName(s);
userList.add(user);
}
return ResultGenerator.getSuccessResult(userList);
}
可以看到,我new了一个User对象(只有id和name属性),id设为“1”,然后for循环nameList,我期望结果是这样的:
{
“id”: “1”,
“name”: “aaa”
},
{
“id”: “1”,
“name”: “bbb”
}
但真实结果却是这样的:
{
“id”: “1”,
“name”: “bbb”
},
{
“id”: “1”,
“name”: “bbb”
}
猜测了一下,应该是List保存的是user对象的引用,第二次修改user对象时,第一次的引用也会改变。
解决方案:对象克隆
1.User类实现clone接口
@Data
public class User implements Cloneable {
private String id;
private String name;
@Override
public Object clone() {
User user = null;
try{
user = (User) super.clone();
}catch(CloneNotSupportedException e) {
e.printStackTrace();
}
return user;
}
}
2.for循环时调用clone方法
public RestResult user(){
List<User> userList = new ArrayList<>();
User user = new User();
user.setId("1");
List<String> nameList = new ArrayList<>();
nameList.add("aaa");
nameList.add("bbb");
nameList.add("ccc");
for (String s:nameList){
User userClone =(User) user.clone();
userClone.setName(s);
userList.add(userClone);
}
return ResultGenerator.getSuccessResult(userList);
}
结果:
{
“id”: “1”,
“name”: “aaa”
},
{
“id”: “1”,
“name”: “bbb”
},
{
“id”: “1”,
“name”: “ccc”
}
问题解决!