浅克隆:不会复制(克隆)对其他对象的引用,其他的字段等都会复制(克隆)
深克隆:所有对其他对象的引用都会复制(克隆),包括自身的字段,方法等
浅克隆的实现:重写父类Object类的clone()方法(一个类需要被克隆,必须实现Cloneable接口,否则调用clone()方法会抛出异常java.lang.CloneNotSupportedException),如需复制(克隆)只需调用clone()方法即可
深克隆的实现:被克隆的类需要实现序列化接口(Serializable),并且它所引用的所有对象都要实现序列化接口(Serializable),因为需要ObjectOutputStream 和 ObjectInputStream 对被克隆的类的需要序列化和反序列化,然后实现深克隆
代码示例:
1. 主要的类
- Person类,对Address类有引用,重写了clone()方法
- Address类
- CloneUtil类,实现深克隆
- Test类,测试类,对比被克隆和克隆的Person实例对Address的引用是否共用一个判断是浅克隆还是深克隆
Person类
package com.huaxin.test;
import java.io.Serializable;
public class Person implements Cloneable, Serializable {
private String name;
private String sex;
private Address address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
Address类
package com.huaxin.test;
import java.io.Serializable;
public class Address implements Serializable {
private String province;
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
}
CloneUtil类
package com.huaxin.test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class CloneUtil{
public static Object deepClone(Serializable ser) {
try {
// 先写到流中
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(ser);
// 从流中读出来
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
Test测试类
package com.huaxin.test;
public class Test {
public static void main(String[] args) {
Address address = new Address();
address.setProvince("湖南");
Person p1 = new Person();
p1.setName("张三");
p1.setSex("男");
p1.setAddress(address);
// 对p1进行浅克隆和深克隆复制
try {
// 判断浅克隆还是深克隆,只需判断是否共用一个子对象Address
System.out.println("---------浅克隆-----------");
Person p2 = (Person) p1.clone();
System.out.println(p1.getAddress() == p2.getAddress());
System.out.println("---------深克隆-----------");
Person p3 = (Person) CloneUtil.deepClone(p1);
System.out.println(p1.getAddress() == p3.getAddress());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
运行结果
运行结果分析:浅克隆对引用的对象没有复制(克隆),所以共用一个引用对象,打印结果为true,深克隆对引用的对象都会复制(克隆),所以打印结果为false