问题描述
public class ListTest { public static void main(String[] args) { List<CoreSltoRecord> list = new ArrayList<CoreSltoRecord>(); CoreSltoRecord c = new CoreSltoRecord(); c.setIsvalid((short)1); list.add(c); List<CoreSltoRecord> listall = new ArrayList<CoreSltoRecord>(); listall.addAll(list); for(CoreSltoRecord r : list){ r.setIsvalid((short)2); }// for(CoreSltoRecord r : listall){// r.setIsvalid((short)2);// } System.out.println(list.get(0).getIsvalid()); //值都是2 System.out.println(listall.get(0).getIsvalid());//值都是2 }}
解决方案
List只是一个容器,里面只记录一个引用(可以理解成c里面的指针),指向CoreSltoRecord。所以现在2个List都同时指向一个CoreSltoRecord了。你随便改哪个List里的东西,其实改的都是同一个CoreSltoRecord,改完另一个list看到的东西也自然会变化。
解决方案二:
list.addAll(Collection);这个方法的底层实现: public boolean addAll(Collection<? extends E> c) {Object[] a = c.toArray(); int numNew = a.length;ensureCapacity(size + numNew); // Increments modCount System.arraycopy(a, 0, elementData, size, numNew); size += numNew;return numNew != 0; }从代码可以看出它只是将原有集合的元素的引用,复制给新的集合,而这里所谓的复制只是复制了每个元素的地址,并不是真正意义上的复制对象,两次操作都是操作的同一个对象。