标签:put 实现 lap col util check ext system tin
该模式的作用就是复制对象,特别是复杂的对象。
1.浅克隆
两个要点:实现Cloneable接口,重写clone()方法
public class Product implements Cloneable{
private String name;
private Date date;
public Product(String name, Date date) {
this.name = name;
this.date = date;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@Override
public String toString() {
return "Product{" +
"name=‘" + name + ‘\‘‘ +
", date=" + date +
‘}‘;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
测试结果:
//浅克隆
public static void main(String[] args) throws CloneNotSupportedException {
Date date1 = new Date();
Product product = new Product("张三",date1);
System.out.println("v1=>"+product +" hashcode=>"+product.hashCode());
Product cloneProduct = (Product) product.clone();
System.out.println("v2=>"+cloneProduct+" hashcode=>"+cloneProduct.hashCode());
date1.setTime(22223333);
System.out.println("===========修改属性后========");
System.out.println("v1=>"+product +" hashcode=>"+product.hashCode());
System.out.println("v2=>"+cloneProduct+" hashcode=>"+cloneProduct.hashCode());
}
打印结果:
v1=>Product{name=‘张三‘, date=Sun Apr 18 16:45:56 CST 2021} hashcode=>1836019240
v2=>Product{name=‘张三‘, date=Sun Apr 18 16:45:56 CST 2021} hashcode=>325040804
===========修改属性后========
v1=>Product{name=‘张三‘, date=Thu Jan 01 14:10:23 CST 1970} hashcode=>1836019240
v2=>Product{name=‘张三‘, date=Thu Jan 01 14:10:23 CST 1970} hashcode=>325040804
结论:原对象和克隆对象的date属性是同一个
2.深克隆
解决上个案例中date属性指向同一个问题。
public class Product implements Cloneable{
private String name;
private Date date;
public Product(String name, Date date) {
this.name = name;
this.date = date;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@Override
public String toString() {
return "Product{" +
"name=‘" + name + ‘\‘‘ +
", date=" + date +
‘}‘;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Product product = (Product)super.clone();
product.date = (Date) this.date.clone();
return product;
}
}
测试结果
//深克隆
public static void main(String[] args) throws CloneNotSupportedException {
Date date1 = new Date();
Product product = new Product("张三",date1);
System.out.println("v1=>"+product +" hashcode=>"+product.hashCode());
Product cloneProduct = (Product) product.clone();
System.out.println("v2=>"+cloneProduct+" hashcode=>"+cloneProduct.hashCode());
date1.setTime(22223333);
System.out.println("===========修改属性后========");
System.out.println("v1=>"+product +" hashcode=>"+product.hashCode());
System.out.println("v2=>"+cloneProduct+" hashcode=>"+cloneProduct.hashCode());
}
打印:
v1=>Product{name=‘张三‘, date=Sun Apr 18 16:56:55 CST 2021} hashcode=>1836019240
v2=>Product{name=‘张三‘, date=Sun Apr 18 16:56:55 CST 2021} hashcode=>325040804
===========修改属性后========
v1=>Product{name=‘张三‘, date=Thu Jan 01 14:10:23 CST 1970} hashcode=>1836019240
v2=>Product{name=‘张三‘, date=Sun Apr 18 16:56:55 CST 2021} hashcode=>325040804
结论:实现的深克隆,date对象也成功克隆,这里有个前提,Date类也实现了Cloneable接口才行。
3.通过序列化来复制对象
深度克隆有个问题:所有属性都要克隆,属性下面可能还有属性,需要层层克隆,非常麻烦,通过流来复制可以减少这些麻烦,但是IO流会增加系统消耗。
前提是被序列化的对象实现Serializable接口,包括它的层层下面的属性,如果某个属性不想序列化,可以通过一些注解来忽略。
public class Product implements Serializable {
private String name;
private Date date;
public Product(String name, Date date) {
this.name = name;
this.date = date;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@Override
public String toString() {
return "Product{" +
"name=‘" + name + ‘\‘‘ +
", date=" + date +
‘}‘;
}
}
测试代码
public class CloneObject {
public static void main(String[] args) {
Date date1 = new Date();
Product product = new Product("张三",date1);
System.out.println("v1=>"+product +" hashcode=>"+product.hashCode());
Product product1 = cloneUtil.cloneObject(product);
System.out.println("v2=>"+product1 +" hashcode=>"+product1.hashCode());
date1.setTime(22223333);
System.out.println("===========修改属性后========");
System.out.println("v1=>"+product +" hashcode=>"+product.hashCode());
System.out.println("v2=>"+product1 +" hashcode=>"+product1.hashCode());
}
}
class cloneUtil {
private cloneUtil() {
}
@SuppressWarnings("unchecked")
public static <T extends Serializable> T cloneObject(T obj) {
T cloneObj = null;
// 序列化
ByteArrayOutputStream bout = null;
ObjectOutputStream oos = null;
try {
bout = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bout);
oos.writeObject(obj);
} catch (IOException e) {
e.printStackTrace();
} finally {
close(oos);
close(bout);
}
// 反序列化
ByteArrayInputStream bin = null;
ObjectInputStream ois = null;
try {
bin = new ByteArrayInputStream(bout.toByteArray());
ois = new ObjectInputStream(bin);
cloneObj = (T) ois.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
} finally {
close(ois);
close(bin);
}
return cloneObj;
}
private static void close(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
打印结果:
v1=>Product{name=‘张三‘, date=Sun Apr 18 17:03:19 CST 2021} hashcode=>1836019240
v2=>Product{name=‘张三‘, date=Sun Apr 18 17:03:19 CST 2021} hashcode=>1072408673
===========修改属性后========
v1=>Product{name=‘张三‘, date=Thu Jan 01 14:10:23 CST 1970} hashcode=>1836019240
v2=>Product{name=‘张三‘, date=Sun Apr 18 17:03:19 CST 2021} hashcode=>1072408673
标签:put 实现 lap col util check ext system tin
原文地址:https://www.cnblogs.com/johnzhao/p/14673947.html