一个类如果想要被克隆,需要实现Cloneabel接口
浅拷贝
创建一个新对象,然后将当前对象的非静态字段复制到该对象,如果字段类型是基本数据类型的,那么对该字段进行复制;如果是引用类型的,则只复制该字段的引用而不复制引用指向的对象。此时新对象里面的引用类型字段相当于是原始对象里面引用类型字段的一个副本,原始对象与新对象里面的引用字段指向同一个对象。因此,修改新对象里面的引用类型字段的内容时,原对象里面的相同字段的内容也会跟着改变
深拷贝
了解了浅拷贝,那么深拷贝是什么也就很清楚了,即将引用类型的属性内容也拷贝一份新的。
实现深拷贝的两种方式:第一种是给需要拷贝的引用类型也实现Cloneable接口并重写clone方法,第二种则是利用序列化。
第一种方式如果类中的引用数据类型太多的话,会非常繁琐,因此不推荐使用。
第二种实现方式–序列化方式。。
这种方式其实就是将对象转成二进制流,然后再把二进制流反序列化成一个java对象,这时候反序列化生成的是一个全新的对象,里面的信息与原对象一样,但是所有的内容都是一份新的。
这种方式需要注意的地方是所有类都需要实现Serializable接口,以便进行序列化操作1
案例
核心代码.
package cm.lhj.review02.demo1;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class DeepClone implements Serializable {
/**
*
*/
private static final long serialVersionUID = 3759117094508223775L;
protected Object deepClone() throws Exception {
// 序列化
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(out);
oout.writeObject(this);
// 反序列化
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
ObjectInputStream iin = new ObjectInputStream(in);
Object readObject = iin.readObject();
iin.close();
return readObject;
}
}
Person类
public class Person extends DeepClone{
/**
*
*/
private static final long serialVersionUID = -5731326376902767304L;
String name;
int age;
Address addr;
public Person(String name, int age, Address addr) {
this.name = name;
this.age = age;
this.addr = addr;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Address getAddr() {
return addr;
}
public void setAddr(Address addr) {
this.addr = addr;
}
}
Address类
public class Address extends DeepClone {
/**
*
*/
private static final long serialVersionUID = 2649670574270213690L;
String address;
String location;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public Address(String address, String location) {
this.address = address;
this.location = location;
}
@Override
public String toString() {
return "Address [address=" + address + ", location=" + location + "]";
}
}
测试类
public class Test {
public static void main(String[] args) throws Exception {
Person p1 = new Person("zs", 47, new Address("中国", "北京"));
Person p2 = (Person) p1.deepClone();
System.out.println(p1);
System.out.println(p2);
System.out.println(p1.addr);
System.out.println(p2.addr);
p2.addr.location = "上海";
System.out.println(p1.addr);
System.out.println(p2.addr);
}
}
输出结果
cm.lhj.review02.demo1.Person@4554617c
cm.lhj.review02.demo1.Person@2503dbd3
Address [address=中国, location=北京]
Address [address=中国, location=北京]
Address [address=中国, location=北京]
Address [address=中国, location=上海]
结果显而易见.