List的深度序列化Demo
今天项目中出现了这个问题。。。就是使用一个List去进行其他的操作,生成一个新的List。但是却将原来的List的值也给改了。。。这应该是引用传递的问题,查了资料发现这是浅拷贝造成的。(ps:使用addAll()方法是浅拷贝)
网上的定义是:
浅拷贝:被复制对象的任何变量都含有和原来的对象相同的值,而任何的对其他对象的引用仍然指向原来的对象。对拷贝后的引用的修改,还能影响原来的对象。
深拷贝:把要复制的对象所引用的对象都复制了一遍,对现在对象的修改不会影响原有的对象。
然后就照着网上的资料自己写了试试。下边的例子就是深拷贝和浅拷贝得到的不同结果。
1 package demo01; 2 3 import java.io.ByteArrayInputStream; 4 import java.io.ByteArrayOutputStream; 5 import java.io.IOException; 6 import java.io.ObjectInputStream; 7 import java.io.ObjectOutputStream; 8 import java.io.Serializable; 9 import java.util.ArrayList; 10 import java.util.List; 11 12 13 public class DeepCopyDemo { 14 15 public static void printList(List<City> list){ 16 for(City t : list){ 17 System.out.println("中文: " + t.getName() + "英文:" + t.getEngName()); 18 } 19 System.out.println("=================================="); 20 } 21 22 23 //深拷贝 24 public static List deepCopy(List src) throws IOException, ClassNotFoundException{ 25 ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); 26 ObjectOutputStream out = new ObjectOutputStream(byteOut); 27 out.writeObject(src); 28 ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray()); 29 ObjectInputStream in =new ObjectInputStream(byteIn); 30 List dest = (List)in.readObject(); 31 return dest; 32 } 33 34 public static void main(String[] args) throws IOException, ClassNotFoundException { 35 List<City> srcList=new ArrayList<City>(); 36 City p1=new City("北京","beijing"); 37 City p2=new City("上海","shanghai"); 38 City p3=new City("广州","guangzhou"); 39 srcList.add(p1); 40 srcList.add(p2); 41 srcList.add(p3); 42 43 List<City> destList=deepCopy(srcList); 44 // List<City> destList=new ArrayList<City>(); 45 // destList.addAll(srcList); 46 printList(destList); 47 srcList.get(0).setEngName("bj"); 48 System.out.println(srcList.get(0) == destList.get(0)); 49 printList(destList); 50 printList(srcList); 51 52 } 53 54 } 55 56 57 58 59 class City implements Serializable{ 60 private static final long serialVersionUID = -7622835197591599128L; 61 private String engName; 62 private String name; 63 64 public City(){}; 65 public City(String name,String engName){ 66 this.name=name; 67 this.engName=engName; 68 } 69 public String getEngName() { 70 return engName; 71 } 72 public void setEngName(String engName) { 73 this.engName = engName; 74 } 75 public String getName() { 76 return name; 77 } 78 public void setName(String name) { 79 this.name = name; 80 } 81 82 }
如果像代码中这样的话,就是深拷贝,结果就是这样的(这样的话就不会影响到原来的List):
如果使用注释掉的那两行代码,而不使用现有的这一行(也就是使用addAll()方法)。就会影响“之前的”List,结果是:
这样应该就很明显的看出效果了。