实现两个类分别为student和address
class Student implements Cloneable{
private String name;
private Address address;
public Student(String name, Address address) {
this.name = name;
this.address = address;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", address=" + address +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
class Address implements Cloneable {
private String address;
public Address(String address) {
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Address{" +
"address='" + address + '\'' +
'}';
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
1. 浅克隆
1.1 利用Object的clone方法
public class Main {
public static void main(String[] args) throws Exception {
Address address = new Address("beijing");
Student student = new Student("zhangsan", address);
Student clone = (Student) student.clone();
System.out.println(student.toString());
System.out.println(clone.toString());
address.setAddress("shanghai");
System.out.println(student.toString());
System.out.println(clone.toString());
}
}
------------------------------结果--------------------------------
Student{name='zhangsan', address=Address{address='beijing'}}
Student{name='zhangsan', address=Address{address='beijing'}}
Student{name='zhangsan', address=Address{address='shanghai'}}
Student{name='zhangsan', address=Address{address='shanghai'}}
2. 深克隆
2.1 重写clone方法
重写clone方法要求所有用到的引用类型都要重写
class Student implements Cloneable{
// ...
@Override
protected Object clone() throws CloneNotSupportedException {
// 克隆基本对象
Student clone = (Student) super.clone();
// 深克隆Address对象
// 克隆一个新的Address对象, 要求Address类如果有引用类型也要重写clone方法
// 利用递归的思想克隆所有的基本类型
clone.address = (Address) this.address.clone();
return clone;
}
// ...
}
class Address implements Cloneable {
// ...
@Override
protected Object clone() throws CloneNotSupportedException {
// 由于Address类只有基本类型可以直接调用Object中的clone方法
return super.clone();
}
// ...
}
测试结果
------------------------结果-------------------------------------
Student{name='zhangsan', address=Address{address='beijing'}}
Student{name='zhangsan', address=Address{address='beijing'}}
Student{name='zhangsan', address=Address{address='shanghai'}}
Student{name='zhangsan', address=Address{address='beijing'}}
2.2 序列化
class Student implements Serializable {
// ...
// 先写再读
public Student deepClone() throws Exception{
// 1. 创建一个 ByteArrayOutputStream,用于存储对象的字节流
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 2. 创建 ObjectOutputStream,将对象序列化为字节流
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
// 3. 将当前对象序列化到字节流中
objectOutputStream.writeObject(this);
objectOutputStream.flush(); // 刷新流,确保所有字节都写入
// 4. 创建一个 ByteArrayInputStream,读取字节流并将其转化为对象
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
// 5. 创建 ObjectInputStream,从字节流中反序列化出对象
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
// 6. 从字节流中反序列化出一个新的对象,并返回这个对象
return (Student) objectInputStream.readObject();
}
//@Override
//protected Object clone() throws CloneNotSupportedException {
// // 克隆基本数据类型
// Student clone = (Student) super.clone();
//
// // 深克隆Address对象
// // 克隆一个新的Address对象, 要求Address类如果有引用类型也要重写clone方法
// // 利用递归的思想克隆所有的基本类型
// clone.address = (Address) this.address.clone();
// return clone;
//}
// ...
}
class Address implements Serializable {
// ...
}
测试结果
-----------------------------结果-----------------------------------
Student{name='zhangsan', address=Address{address='beijing'}}
Student{name='zhangsan', address=Address{address='beijing'}}
Student{name='zhangsan', address=Address{address='shanghai'}}
Student{name='zhangsan', address=Address{address='beijing'}}