思想
将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。
浅克隆
package com.principle.prototype;
import java.util.Date;
public class Prototype implements Cloneable {
private int temp;
private Date date;
public int getTemp() {
return temp;
}
public void setTemp(int temp) {
this.temp = temp;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
protected Object clone() throws CloneNotSupportedException {
Prototype prototype = (Prototype) super.clone();
return prototype;
};
public static void main(String[] args) throws CloneNotSupportedException {
Prototype prototype=new Prototype();
prototype.setTemp(19);
Date date=new Date(212121121L);
prototype.setDate(date);
Prototype prototype2=(Prototype) prototype.clone();
System.out.println(prototype);
System.out.println(prototype.getTemp());
System.out.println(prototype.getDate());
System.out.println(prototype2);
System.out.println(prototype2.getTemp());
System.out.println(prototype2.getDate());
prototype.setTemp(12);
date.setTime(1212121212);
System.out.println(prototype.getDate());
System.out.println(prototype2.getDate());
System.out.println(prototype.getTemp());
System.out.println(prototype2.getTemp());
}
}
打印结果:
com.principle.prototype.Prototype@15db9742
19
Sat Jan 03 18:55:21 CST 1970
com.principle.prototype.Prototype@5c647e05
19
Sat Jan 03 18:55:21 CST 1970
Thu Jan 15 08:42:01 CST 1970
Thu Jan 15 08:42:01 CST 1970
12
19
可以看出,如果参数是对象类型,修改值后,克隆的属性值也跟着改变;如果是基本类型就不变了;说明在浅克隆中,对象属性克隆的是引用地址,他们引用的还是同一个对象。
深克隆:
package com.principle.prototype;
import java.util.Date;
public class Prototype3 implements Cloneable {
private int temp;
private Date date;
public int getTemp() {
return temp;
}
public void setTemp(int temp) {
this.temp = temp;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
protected Object clone() throws CloneNotSupportedException {
Prototype3 prototype = (Prototype3) super.clone();
prototype.date=(Date) this.date.clone();
return prototype;
};
public static void main(String[] args) throws CloneNotSupportedException {
Prototype3 prototype=new Prototype3();
prototype.setTemp(19);
Date date=new Date(212121121L);
prototype.setDate(date);
//修改代码
Prototype3 prototype2=(Prototype3) prototype.clone();
System.out.println(prototype);
System.out.println(prototype.getTemp());
System.out.println(prototype.getDate());
System.out.println(prototype2);
System.out.println(prototype2.getTemp());
System.out.println(prototype2.getDate());
prototype.setTemp(12);
date.setTime(1212121212);
System.out.println(prototype.getDate());
System.out.println(prototype2.getDate());
System.out.println(prototype.getTemp());
System.out.println(prototype2.getTemp());
}
}
打印结果:
com.principle.prototype.Prototype3@15db9742
19
Sat Jan 03 18:55:21 CST 1970
com.principle.prototype.Prototype3@5c647e05
19
Sat Jan 03 18:55:21 CST 1970
Thu Jan 15 08:42:01 CST 1970
Sat Jan 03 18:55:21 CST 1970
12
19
可以看出,只是修改了一小部分,就是在克隆的代码中,对对象也进行了克隆处理,这样就不是同一个引用地址,而是各自的新对象。
通过序列化和反序列化来实现深复制
package com.principle.prototype;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;
public class Prototype3 implements Cloneable,Serializable {
private int temp;
private Date date;
public int getTemp() {
return temp;
}
public void setTemp(int temp) {
this.temp = temp;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
protected Object clone() throws CloneNotSupportedException {
Prototype3 prototype = (Prototype3) super.clone();
prototype.date=(Date) this.date.clone();
return prototype;
};
public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
Prototype3 prototype=new Prototype3();
prototype.setTemp(19);
Date date=new Date(212121121L);
prototype.setDate(date);
System.out.println(prototype);
System.out.println(prototype.getTemp());
System.out.println(prototype.getDate());
//修改代码
//使用序列化和反序列化实现深复制
ByteArrayOutputStream bos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(bos);
oos.writeObject(prototype);
byte[] bytes=bos.toByteArray();
ByteArrayInputStream bis=new ByteArrayInputStream(bytes);
ObjectInputStream ois=new ObjectInputStream(bis);
Prototype3 p3=(Prototype3) ois.readObject();
System.out.println("修改原型对象的属性值");
date.setTime(2343234L);
System.out.println(prototype.getDate());
p3.setTemp(22);
System.out.println(p3);
System.out.println(p3.getTemp());
System.out.println(p3.getDate());
}
}
打印结果:
com.principle.prototype.Prototype3@15db9742
19
Sat Jan 03 18:55:21 CST 1970
修改原型对象的属性值
Thu Jan 01 08:39:03 CST 1970
com.principle.prototype.Prototype3@28d93b30
22
Sat Jan 03 18:55:21 CST 1970
通过序列化和反序列化后就会重新生成一个新的对象
当new一个对象比较耗时的时候,就可以用原型模式来实例化对象。