在一个List中add()
了一个对象后,之后再没有改变这个List,某个时间点取出List中的数据, 却发现取出的数据已经发生了变化。
这个bug排查了好久,才发现是因为当初add的对象在别的类中被改变了!
这就是List的add方法隐藏的坑,且当原对象不在一个类中时,bug原因不容易被发现。
原来当我们调用add()
或addAll()
方法时,添加的是引用,当原对象改变时,list中的数据会相应改变。
来看这个示例:
class People {
String name;
}
List<People> peoples = new ArrayList<>();
People p = new People();
p.name = "Sbingo";
peoples.add(p);
System.out.print(peoples.get(0).name + "\n");
p.name = "Sbingo changed";
System.out.print(peoples.get(0).name + "\n");
执行后输出:
Sbingo
Sbingo changed
可见改变对象p后,peoples 中的数据确实发生了变化!
But!!!
这对String、int等元类型数据不是一回事。
看以下示例:
List<String> list = new ArrayList<>();
String a = "string a";
list.add(a);
System.out.print(list.get(0) + "\n");
a = "a changed";
System.out.print(list.get(0) + "\n");
List<Integer> list1 = new ArrayList<>();
int b = 1;
list1.add(b);
System.out.print(list1.get(0) + "\n");
b = 2;
System.out.print(list1.get(0) + "\n");
执行后输出:
string a
string a
1
1
可见,变量a、b的改变并没有影响list、list1 中的数据。
stackoverflow上也有相关的问答:
https://stackoverflow.com/questions/7080546/add-an-object-to-an-arraylist-and-modify-it-later