java深克隆和浅克隆
java中之所以会有深浅克隆的问题,主要原因是其数据类型存在基本数据类型和对象类型;
浅克隆无法实现对象类型的真正克隆,它只能实现对象的引用复制(这样所有的引用其实是指向同一个对象的,这样任何一个引用做出的修改都会反映到所有引用),它与深度克隆的区别也在于此;
要实现深度克隆有两个方法:
1、对象实现Cloneable接口,重写clone方法;
public Object clone() {
Car car = (Car)super.clone();
// 克隆对象属性,Cycle也必须实现Cloneable接口,重写clone方法
car.cycle = (Cycle)cycle.clone();
return car;
}
2、使用序列化的方式;
序列化就是将对象写到流的过程,写到流中的对象是原有对象的一个拷贝,而原对象仍然存在于内存中。通过序列化实现的拷贝不仅可以复制对象本身,而且可以复制其引用的成员对象,因此通过序列化将对象写到一个流中,再从流里将其读出来,可以实现深克隆。需要注意的是能够实现序列化的对象其类必须实现Serializable接口,否则无法实现序列化操作。

1 public static void main(String[] args) throws IOException, ClassNotFoundException { 2 Car car = new Car(); 3 car.setAddress("中国陕西西安"); 4 car.setLearn(10000); 5 Car car1 = new Car(); 6 car1.setAddress("中国陕西渭南"); 7 car1.setLearn(20000); 8 Person p1 = new Person(); 9 p1.setAge(18); 10 p1.setCar(car); 11 p1.setName("p1"); 12 Person p2 = new Person(); 13 p2.setAge(28); 14 p2.setCar(car1); 15 p2.setName("p2"); 16 Home home = new Home(); 17 home.setAddress("中国陕西富平"); 18 home.setCount(2); 19 home.setPersions(p1); 20 home.setPersions(p2); 21 System.out.println(home); 22 23 // 使用Protobuf克隆home对象 24 RuntimeSchema<Home> schema = RuntimeSchema.createFrom(Home.class); 25 26 byte[] serializerResult = ProtobufIOUtil.toByteArray(home, schema, LinkedBuffer.allocate(256)); 27 28 Home cloneHome = schema.newMessage(); 29 ProtobufIOUtil.mergeFrom(serializerResult, cloneHome, schema); 30 31 System.out.println(cloneHome); 32 33 home.setCount(6); 34 // 传统方式clone 35 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 36 ObjectOutputStream oos = new ObjectOutputStream(bos); 37 oos.writeObject(home); 38 byte[] arr = bos.toByteArray(); 39 ByteArrayInputStream bis = new ByteArrayInputStream(arr); 40 ObjectInputStream ois = new ObjectInputStream(bis); 41 Home normalCloneHome = (Home)ois.readObject(); 42 ois.close(); 43 bis.close(); 44 oos.close(); 45 bos.close(); 46 47 System.out.println(normalCloneHome); 48 }