深克隆与浅克隆

克隆是将一个对象复制成另一个完全相同的对象,但内存地址不同,修改原对象的值,克隆出的对象的值不会发生改变。
若某个类的对象需要进行克隆=>(深拷贝、浅拷贝)时,则这个类必须要实现 Cloneable 接口【若果没有实现这个接口,则会抛出
CloneNotSupportedException(克隆不支持异常)】,并且需要在这个类中重写 Object 类中的 clone() 方法。

浅拷贝=>仅仅复制对象本身,基本数据类型进行复制后修改某一对象的属性,不会让其他对象也被修改,而当类中包含其他类的对象

时,仅复制其他类的对象的内存地址,修改一处后会使其他对象都被修改。

例: protected Weapon clone() throws CloneNotSupportedException {
	
	return (Weapon)super.clone();
}

深拷贝(标准)=>利用浅拷贝的方式将其他类的对象向下一层进行复制,然后通过set方法设置给上一层,最终将底层的所有对象全部复制,

修改任何值,都不会对其他属性造成影响。
例:protected Robot clone() throws CloneNotSupportedException {
Robot robot = (Robot)super.clone();
Weapon weapon = robot.getWeapon().clone();
robot.setWeapon(weapon);;
return robot;
}
protected Weapon clone() throws CloneNotSupportedException {

	return (Weapon)super.clone();
}

深拷贝(序列化)=>功能和标准的深拷贝相同,但序列化深拷贝是直接将对象序列化成字节流,再将字节流反序列化成为新的对象。

使用这种方法不用实现 Cloneable 接口,但是当前类和其使用到的类都需要实现 Serializable 接口,然后再该类中自定义一个克隆方法(deepClone)。
首先利用 byteArrayOutputStream(字节数组输出流) 和 ObjectOutputStream (对象输出流)将对象序列化成字节流,然后利用
byteArraryInputStream(字节数组输入流)和 ObjectInputStream(对象输入流)将字节流反序列化成为新的对象

例:protected Robot deepClone() throws Exception {
	将当前对象“Robot对象”转化为字符流(序列化)
	ByteArrayOutputStream bos = new ByteArrayOutputStream();
	ObjectOutputStream oos = new ObjectOutputStream(bos);
	oos.writeObject(this);
	
	将字节流转换成“新的Robot对象”(反序列化)
	ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
	ObjectInputStream ois = new ObjectInputStream(bis);
	Robot robot = (Robot)ois.readObject();
	
	return robot;
}
标准深拷贝和序列化深拷贝的区别:当一个对象底层包含有若干个对象时,标准的深克隆从最底层开始克隆,效率较低。
			     而序列化深拷贝直接将最外层的对象整体的序列化,再利用反序列化克隆出一个新的对象,效率较高。
上一篇:一文带你了解基于视觉的机器人抓取自学习(Robot Learning)


下一篇:[LeetCode] 657. Robot Return to Origin