2、深克隆:
二、Prototype模式与深、浅克隆:
使用Object.clone()方法进行的克隆是“浅克隆”-被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。 换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
浅克隆的步骤如下:
①为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。
②在派生类中覆盖基类的clone()方法,并声明为public。
③在派生类的clone()方法中,调用super.clone()。
④在派生类中实现Cloneable接口。
为什么我们在派生类中覆盖Object的clone()方法时,一定要调用super.clone()呢?在运行时刻,Object中的clone()要识别出你要复制的是哪一个对象,然后为此对象分配空间,并进行对象的复制,将原始对象的内容一一复制到新对象的存储空间中。
要实现“深克隆”-被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
深克隆需要使用Java中提供的对象串行化功能-即把要复制的对象写入到一个缓冲流,然后通过输入流读入,完成对象的复制
例:
try {
// 在内存中开辟一块缓冲区,用于将自身写入
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bout);
// 通过Serialization机制将自身写入该缓冲区
out.writeObject(this);
out.close();
// 找到刚才开辟的缓冲区准备读取
ByteArrayInputStream bin = new ByteArrayInputStream(bout
.toByteArray());
ObjectInputStream in = new ObjectInputStream(bin);
// 将刚才写入的内容读入一个新的对象
Object ret = in.readObject();
in.close();
// 返回这个对象,拷贝完毕
return ret;
} catch (Exception e) {
e.printStackTrace();
return null;
}
三、Prototype模式的优、缺点和适用场合:
使用Prototype模式的一个好处就是可以节省大量的接口实现类的编写。采用工厂模式的话,如果分别为用户指定的每种场合都提供一个用户接口工厂类,将会为我们带来繁重的工作量。未来避免用户接口工厂类不断增加,可以考虑使用Prototype模式。
而Prototype模式的一个致命的缺点是:Java中的原型方法不允许新对象拥有与父对象不同的方法。这时候,在使用原型方法之前,需要仔细考虑原型方法的利弊,甚至要试一下Prototype模式是否满足需求。
综上所述:Prototype模式最适用的场合应该是:当几个对象的类仅在属性上存在一点差异,而行为上完全相同时。可以在复制一个原型对象后,对其属性进行细小的微调,从而实现定制化的目的。