首先需要了解对象深、浅复制的概念:
浅复制:将一个对象复制后,基本数据类型(如int,String,boolean)的变量都会重新创建,而引用类型,指向的还是原对象(或数组)所指向的。
① 拷贝时候虽然创建了新的对象,但是并没有调用构造方法,直接复制堆上面的对象
② 对象中的引用对象并没有拷贝,引用的地址还是和原对象一致
③ 基本类型或者 String 默认会拷贝
深复制:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。简单来说,就是深复制进行了完全彻底的复制,而浅复制不彻底。
要实现深复制,需要采用流的形式读入当前对象的二进制输入,再写出二进制数据对应的对象。
实现见原型模式。
·clone()方法的使用
- 实现Cloneable接口;
- 重写clone();
- 内部调用super.clone()即Obejct.clone();
- clone()修饰符为public
public class Prototype implements Cloneable {
public Object clone() throws CloneNotSupportedException {
return (Prototype) super.clone();
}
}
·重点内容Java中如果clone为什么必须实现Cloneable接口
1. clone()是native方法,在object中申明如下:
protected native Object clone() throws CloneNotSupportedException;
2. 不实现Cloneable接口,调用clone()时会抛CloneNotSupportedException异常。
3. Cloneable接口只是一个标志类,用来标识实现该接口的类具有克隆功能
浅复制实现如下:
/* 浅复制 */
public Object clone() throws CloneNotSupportedException {
return (Prototype) super.clone();
}
深复制则可以基于Java中的序列化和反序列化实现。
1. 首先要被复制的类要实现Serializable接口,这是一个空接口,作用与Cloneable类似,表明当前类支持序列化和反序列化。
2. 定义并实现深复制方法(方法命名可以随意取),这里叫deepClone吧。
public CloneClass deepClone() throws IOException, ClassNotFoundException {
/* 写入当前对象的二进制流 */
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
/* 读出二进制流产生的新对象 */
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (CloneClass) ois.readObject();
}
代码实现如下:
/* 深复制 */
public