原型模式总的来说就是一个类实现Cloneable的接口
例如小🐏类
public class Sheep implements Cloneable{
private String name;
private int weight;
public Sheep(String name, int weight) {
this.name = name;
this.weight = weight;
}
public String getName() {
return name;
}
public int getWeight() {
return weight;
}
public void print()
{
System.out.println("name= " + name + "weight=" +weight);
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
调用他
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Sheep sheep = new Sheep("ASD",213);
Sheep sheep1 = (Sheep)sheep.clone();
sheep.print();
sheep1.print();
System.out.println(sheep==sheep1);
System.out.println(sheep.getName()==sheep1.getName());
}
}
但是这样的拷贝对于sheep的第一个参数name来说只能浅拷贝,不能深拷贝。
不懂深浅拷贝的兄弟建议去其他博客先看一下。造成的后果就是第一只羊改名,连带着第二只羊的名字也改变了。
解决方法
1.重写Cloneable的 clone方法
public class Ear implements Cloneable{
int i=1;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public Ear() {
}
}
public class Sheep implements Cloneable{
private Ear ear=new Ear(); //小羊的耳朵
private int weight=1;
public Ear getEar() {
return ear;
}
public int getWeight() {
return weight;
}
public void setEar(Ear ear) {
this.ear = ear;
}
public void setWeight(int weight) {
this.weight = weight;
}
public void print()
{
System.out.println("Ear= " + ear.toString() + "weight=" +weight);
}
@Override
protected Object clone() throws CloneNotSupportedException {
Sheep sheep = (Sheep) super.clone();
sheep.setEar((Ear) ear.clone());
return sheep;
}
}
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Sheep sheep = new Sheep();
Sheep sheep1 = (Sheep)sheep.clone();
sheep.print();
sheep1.print();
System.out.println(sheep==sheep1);
System.out.println(sheep.getEar()==sheep1.getEar());
}
}
这样就可以做到每只小羊的耳朵都是独一无二的了。
2.通过序列化实现
public Object deepClone()
{
Object o;
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);
o = ois.readObject();
}catch (Exception e)
{
e.printStackTrace();
return null;
}finally {
try {
bos.close();
oos.close();
bis.close();
ois.close();
}catch (Exception e2)
{
e2.printStackTrace();
}
}
return o;
}
本段代码可以直接用。注意所使用的类要实现Serializable接口,所组合或者聚合的类也要是西安Serializable接口。