实现对象的深度克隆

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方法克隆对象,让问题在编译的时候就暴露出来
posted @ 2019-12-04 23:13  若水一剑  阅读(840)  评论(0编辑  收藏  举报