原型模式就是从一个对象再创建另外一个可定制的对象
这里要注意的是浅复制,即对象的成员变量是对象,但是并没有复制该成员变量的地址;
贴代码举例:
/**目标类
* Created by Tom on 2018/3/7.
*/
public class Prototype implements Cloneable {
public String name;
CloneTarget target = null;
}
/**目标类
* Created by Tom on 2018/3/7.
*/
public class CloneTarget extends Prototype {
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class CloneTest {
public static void main(String[] args) {
CloneTarget p = new CloneTarget();
p.name = "Tom";
p.target = new CloneTarget();
System.out.println(p.target);
try {
CloneTarget obj = (CloneTarget) p.clone();
System.out.println(obj.target);
} catch (Exception e) {
e.printStackTrace();
}
}
}
打印的结果,两个traget对象是同一个地址,也就说并没有复制成员对象的地址,成员对象还是原有的对象。
解决方案:
public class QiTianDaSheng extends Monkey implements Cloneable,Serializable {
public JinGuBang jinGuBang;
public QiTianDaSheng(){
//只是初始化
this.birthday = new Date();
this.jinGuBang = new JinGuBang();
}
@Override
protected Object clone() throws CloneNotSupportedException {
return this.deepClone();
}
public Object deepClone(){
try{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
QiTianDaSheng copy = (QiTianDaSheng)ois.readObject();
copy.birthday = new Date();
return copy;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}
将目标对象序列化,反序列化就可以生产出一个新的对象。
QiTianDaSheng q = new QiTianDaSheng();
QiTianDaSheng n = null;
try {
n = (QiTianDaSheng)q.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
System.out.println(q.jinGuBang == n.jinGuBang);
生产可以看到齐天大圣类中的金箍棒是一个新对象,打印出false;
以上