1.clone的由来
创建一个对象的一个副本--按照原对象,创建一个新的对象,复制对象的内容。
1.1new对象和反射创建对象的弊端
1.2使用clone方法创建对象
1.在需要调用clone方法的对象上添加实现Cloneable接口
2.复写clone方法,在自己的clone方法中调用父类的clone方法,将返回值类型强转成本类类型,将当前clone方法的修饰符改为public
3.在测试中调用对象的clone方法
通过使用clone方法,我们发现大大的减少了创建重复对象代码。这也就是clone方法存在的意义I
2.clone对象和原对象的关系
结论:通过测试发现克隆出来的对象虽然不一致,但是底层的成员变量的哈希值是一致的。
这种复制我们称之为: ** 浅表复制**。
浅表复制的内存结构:
3.能不能让克隆对象的其中的成员变量也成为新的变量
3.1浅表复制的弊端:成员变量不变
3.2.深表复制:局部变量也会变化
核心步骤
public class Person implements Cloneable {
private String name;
private int age;
private Children children;
@Override
public Person clone() throws CloneNotSupportedException {
Person clone = (Person) super.clone();
clone.setChildren(children.clone());
return clone;
}
}
4.成员变量不实现clone接口的情况下进行深度复制
4.1使用clone接口完成深度复制的弊端
1.重复实现cloneable接口
2.重复实现clorpe方法
3.重复改写Person类的clone方法
4.2使用IO流的方式进行复制操作(深层复制)
4.2.1 可以解决重复编写代码的问题
简单演示: 一个对象的复制.
开发步骤:
1.创建ByteArrayOutputStream,将数据可以转换成字节
2.创建ObjectOutputStream,关联ByteArrayOutputStream
3.使用ObjectOutputStream的writeObject,读取要复制的对象
4.使用ByteArrayInputStream读取ByteArrayOutputStream的转换的对象字节数据
5.创建ObjectInputStream读取对象字节数据,创建新的对象
package clone;
import lombok.Data;
import java.io.*;
public class Person implements Serializable,Cloneable {
private String name;
private int age;
private Children children;
private Grandson grandson;
------
@Override
protected Person clone() throws CloneNotSupportedException {
try {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bout);
out.writeObject(this);
ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
ObjectInputStream in = new ObjectInputStream(bin);
Person person = (Person) in.readObject();
return clone();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}