fin*_*nnw 7 java serialization serializable deep-copy cloneable
如果Java类实现了Serializable接口但没有公共clone()方法,通常可以创建如下的深层副本:
class CloneHelper {
@SuppressWarnings("unchecked")
public static <T extends Serializable> T clone(T obj) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
oos.close();
byte[] bytes = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
T copy = (T) ois.readObject();
ois.close();
return copy;
} catch (ClassNotFoundException ex) {
// Shouldn't happen
throw new Error(ex);
} catch (IOException ex) {
// Probably a bug in T's custom serialization methods
throw new RuntimeException(ex);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我经常遇到像这样的第三方库类,并采用上面那样的黑客攻击.我甚至ObjectOutputStream偶尔会延长副本的颜色.它从来没有造成严重的问题,除了效率低(编码/解码速度慢,临时序列化图形可能消耗大量内存.)
如果使用这种技术不安全,那么该类可能不应该被声明Serializable.
所以我想知道的是,如果你的类是Serializable什么,可能会阻止你定义一个公共clone()方法(使用Cloneable接口或复制构造函数?)
相关:使用Java复制对象
嗯,您是说序列化机制是间接“克隆”对象的一种方法。这当然不是它的主要功能。它通常用于让程序通过网络传输对象,或存储并稍后读取它们。您可能期望以这种方式使用对象,并实现 Serialized,而不期望代码在本地克隆对象,并且不实现 Cloneable。
代码通过序列化解决这个问题的事实表明,代码正在以作者不希望的方式使用对象,这可能是作者或调用者的“错误”,但这并不意味着一般情况下可序列化和可克隆一起走。
另外,我不确定clone()是否“损坏”,以及正确实现起来是否困难。恕我直言,复制构造函数更容易使用并且正确。
| 归档时间: |
|
| 查看次数: |
2932 次 |
| 最近记录: |