1、原型模式
就是从一个现有的对象克隆一个新的对象,克隆出来的新对象与原来的对象赋值一样。她的本质就是字节码复制,性能高于反射。
浅拷贝
能够直接拷贝其实际内容,包括八大基本类型和String类型。
深拷贝
需要重写clone()方法。
克隆不执行构造方法,直接走字节码复制。
应用场景:拷贝复制的对象
2、代码实现
(1)浅拷贝
package pattern.prototype.simpleclone;
public class Prototype implements Cloneable{
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
package pattern.prototype.greatestsage;
public class CloneTest {
public static void main(String[] args) {
TheGreatestSage copy = new TheGreatestSage();
copy.change();
}
}
package pattern.prototype.simpleclone;
import java.util.ArrayList;
import java.util.List;
public class ConcretePrototype extends Prototype{
private String name;
private int age;
public List<String> list = new ArrayList<String>();
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;
}
}
package pattern.prototype.simpleclone;
/**
* 原型模式测试类
* @author 33396
*
*/
public class CloneTest {
public static void main(String[] args) {
ConcretePrototype cp = new ConcretePrototype();
cp.setName("Jordan");
cp.setAge(23);
cp.list.add("MVP");
ConcretePrototype cloneObj;
try {
cloneObj = (ConcretePrototype) cp.clone();
//通过字节码复制产生新对象,故而下面结果为false
System.out.println(cp==cloneObj);
System.out.println(cloneObj.getName()+"----"+cloneObj.getAge());
//list对象应用地址相同,指向同一个,故而下面结果为true
System.out.println(cp.list==cloneObj.list);
/**
* 浅拷贝能够直接拷贝其实际内容,包括八大基本类型和String类型。
*
*/
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
(2)深拷贝
package pattern.prototype.greatestsage;
import java.util.Date;
public class Monkey {
protected int height;
protected int weight;
protected Date birthday;
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
package pattern.prototype.greatestsage;
import java.io.Serializable;
public class GoldRingedStaff implements Serializable{
private float height = 100;
private float diameter = 100;
private void big() {
this.height *= 2;
this.diameter *= 2;
}
private void little() {
this.height /= 2;
this.diameter = 2;
}
public float getHeight() {
return height;
}
public void setHeight(float height) {
this.height = height;
}
public float getDiameter() {
return diameter;
}
public void setDiameter(float diameter) {
this.diameter = diameter;
}
}
package pattern.prototype.greatestsage;
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 TheGreatestSage extends Monkey implements Cloneable,Serializable{
GoldRingedStaff staff;
public TheGreatestSage() {
this.staff = new GoldRingedStaff();
this.height = 160;
this.weight = 40;
this.birthday = new Date();
System.out.println("克隆不执行构造方法,直接走字节码复制。");
}
@Override
protected Object clone() {
/*try {
return super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}*/
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
//序列化
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(this);
//反序列化
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
TheGreatestSage copyGreatestSage = (TheGreatestSage) ois.readObject();
copyGreatestSage.setBirthday(new Date());
return copyGreatestSage;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
bos.close();
oos.close();
bis.close();
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void change() {
TheGreatestSage copygreatestSage = (TheGreatestSage) clone();
System.out.println("齐天大圣本尊生日:"+this.getBirthday().getTime());
System.out.println("克隆的齐天大圣本尊生日:"+copygreatestSage.getBirthday().getTime());
System.out.println("大圣本尊与克隆大圣是否同一个对象:"+(this == copygreatestSage));
System.out.println("金箍棒是否同一个:"+(this.staff == copygreatestSage.staff));
}
}
package pattern.prototype.greatestsage;
public class CloneTest {
public static void main(String[] args) {
TheGreatestSage copy = new TheGreatestSage();
copy.change();
}
}