扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:builder.com.cn 2007年6月29日
关键字:
可克隆的接口和深拷贝
默认情况下,Java中的类并不支持克隆;默认执行clone()方法会生成一个CloneNotSupportedException异常。你不应当考虑执行clone()方法。
记住,你必须使其公开,在方法内,你的首先操作必须为super.clone()。想要允许克隆的类必须执行标记接口Cloneable。虽然默认执行Object.clone只会执行一次浅拷贝。需要深拷贝时,类必须忽略克隆才能提供一个定制的执行。基本上,如果你想要使类对象公开可克隆,你需要使用以下代码:
class Test implements Cloneable
{
...
public Object clone()
{
try
{
return super.clone();
}
catch ( CloneNotSupportedException e )
{
return null;
}
}
...
}
如果你乐于接受一个受保护的克隆,它只会盲目地复制对象的源代码,你就不必重新定义你自己的版本。但是,你往往想要一个公开克隆。(注意:你不能建立一个私有或默认范围克隆;你只能提高忽略时的可见性。)
可能出现的问题及解决方案
由于clone()方法受到保护,子类必须用一个公开方法忽略这个受保护的方法,明确同意其为可克隆。所有Collections类完成这个任务。子类还必须对Object.clone()中的默认克隆机制执行Cloneable。
如果你知道一个对象拥有公开clone()方法,但在编译时你不知道这个对象的类型,这时就会出现问题。例如,假设宣称x为一个Object。你不能只是调用x.clone(),因为Object.clone()受到保护。
如果Cloneable定义了一个公开clone()方法,你可以使用((Cloneable) x).clone(),但它不能。你要么必须列举所有你认为可能为x的类,或者求助于反射。
在你试图深拷贝一个复杂的对象时还会遇到另一个问题。你假定所有成员对象变量的clone()方法也执行深拷贝;这种假设具有相当大的风险。你必须控制所有类的代码,或者你必须知道深拷贝操作涉及的所有类都以正确的方式完成了拷贝。
解决这些问题的一个方法是使用序列化克隆。序列化常用于将对象发送到某处(如文件中或网络内),以便其他人稍后可以重建它们。你可以利用序列化立即自行重建对象。
如果对象完全可序列化,那么重建应为一个可靠的拷贝。在正常使用序列化的情况下,原始对象远非一个可靠的拷贝;它可能在世界的另一面,在网络连接的远端。你可以确信修改拷贝不会对原始对象造成影响。
Peter V. Mikhalenko是一名Sun认证专家,现任德意志银行商业顾问。
责任编辑:张琎
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者