实现对象的深度克隆
Posted qdmpky
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现对象的深度克隆相关的知识,希望对你有一定的参考价值。
1.方式一
实现Cloneable接口并重写 Object类中的 clone()方法
2. 方式二
(实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆)
2.1 User类和Car的准备
package cn.qdm.ceshi;
import java.io.Serializable;
public class User implements Serializable{
private String name;
private Integer age;
private Car car; //开的车
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + ", car=" + car + "]";
}
public User(String name, Integer age, Car car) {
super();
this.name = name;
this.age = age;
this.car = car;
}
public User() {
super();
// TODO Auto-generated constructor stub
}
}
package cn.qdm.ceshi;
import java.io.Serializable;
public class Car implements Serializable{
private String brand; //品牌
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
@Override
public String toString() {
return "Car [brand=" + brand + "]";
}
public Car(String brand) {
super();
this.brand = brand;
}
public Car() {
super();
// TODO Auto-generated constructor stub
}
}
2.2 克隆工具类的准备
package cn.qdm.ceshi;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class MyUtil {
private MyUtil() {
throw new AssertionError();
}
//实现深度克隆的工具方法
public static<T extends Serializable> T clone(T obj) throws Exception{
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bout);
oos.writeObject(obj);
ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bin);
return (T) ois.readObject();
//ByteArrayOutputStream和ByteArrayInputStream是基于内存的流只要垃圾回收器清理对象就能够释放资源,不同于外部资源(如文件流)的释放
}
}
2.3 测试类
package cn.qdm.ceshi;
public class CloneTest {
public static void main(String[] args) {
User user1 = new User("张三", 18, new Car("BYD"));
//深度克隆
try {
User user2 = MyUtil.clone(user1);
//修改克隆对象user2的关联汽车属性
user2.getCar().setBrand("迈凯伦P1");
//打印原来对象不影响关联对象
System.out.println(user1);
System.out.println(user2);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2.4 运行结果
3.注意:
基于序列化和反序列化实现的克隆不仅仅是深度克隆,更重要的是用过泛型限定,可以检查出
要克隆的对象是否支持序列化,这项检查是编译器完成的,不是在运行时抛出异常,这种方案明显
优于使用Obeject类的clone方法克隆对象,让问题在编译的时候就暴露出来
以上是关于实现对象的深度克隆的主要内容,如果未能解决你的问题,请参考以下文章