在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的。Clone 有缺省行为,super.clone();他负责产生正确大小的空间,并逐位复制。使用clone()来复制一个对象,clone()从Object类继承。所有具有clone功能的类都有一个特性,那就是它直接或间接地实现了Cloneable接口。
protected native Object clone() throws CloneNotSupportedException;
可以看出它是一个protected方法,所以我们不能简单地调用它;关键字native,表明这个方法使用java以外的语言实现。
对于 object x,
x.clone() != x
x.clone().getClass() == x.getClass()
x.clone().equals(x)
以上返回的值都为true
要说明的有两点:一是拷贝对象返回的是一个新对象,而不是一个引用。二是拷贝对象与用new操作符返回的新对象的区别就是这个拷贝已经包含了一些原来对象的信息,而不是对象的初始信息。
1.浅复制与深复制概念
⑴浅复制(浅克隆):被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
⑵深复制(深克隆)
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
public class TestClone1 implements Cloneable{
int count;
TestClone1 next;
public TestClone1(int count) {
this.count=count;
if(count>0)
next=new TestClone1(count-1);
}
void add(){
count++;
if(next!=null)
next.count++;
}
public String toString(){
String s=String.valueOf(count)+" ";
if(next!=null)
s+=next.toString();
return s;
}
public Object clone(){
Object o=null;
try{
o=super.clone();//如果没有实现cloneable,将会抛出CloneNotSupported异常
}
catch(CloneNotSupportedException e){
System.err.println("cannot clone");
}
return o;
}
public static void main(String[] args){
TestClone1 t=new TestClone1(1);
System.out.println("t="+t);
TestClone1 t1=(TestClone1)t.clone();
System.out.println("t1="+t1);
t.add();
System.out.println("after added/nt t="+t+"/nt1="+t1)
}
}
在这个例子中创建t相当于两个相连的TestClone1实例,而在调用了t的add方法之后,意想不到的结果出现了:
t=1 0
t1=1 0
after added
t t=2 1
t1=1 1
t1也发生了改变。实际上Object.clone()进行的复制有着"bitwise"原则,也就是逐位复制。对于一个对象中定义的对象,它只是简单的复制这个对象的引用。这也就是常说的浅层拷贝(shallow copy)。想要执行深层拷贝(deep copy),只需要在TestClone1 t1=(TestClone1)t.clone();后面加上t1.next=(TestClone1)t.next.clone();就能得到:
t=1 0
t1=1 0
after added
t t=2 1
t1=1 0
这个正确的结果。
分享到:
相关推荐
在使用高版本版KEIL时,提示要升级固件,升级后就出现JLINK is Clone的提示!“the emulator is JLink-Clone, the segger software only support orginal segger device” 然后闪退,IDE崩溃关闭! 解决方案: 1....
支持多个git库clone,提交等常用操作,用户需要根据实际情况微调参数
git clone 最新版 不多说上资源 好用测试ok git clong git clone 最新版 不多说上资源 好用测试ok git clong
中文语音克隆内含数据集和预训练模型:voice clone
Jlink-clone解决办法,替换文件
Caffe2 Windows third_party(git clone失败或速度慢时可用)
Clone10-EX-LV2
An effective and efficient assembly code clone search engine can greatly reduce the effort of this process, since it can identify the cloned parts that have been previously analyzed. The assembly ...
本人用的JLINK仿真器.在使用新版KEIL时,提示要升级固件,升级后就出现JLINK is Clone的提示。在网上找了许多关于修复的资料,都觉得不是很好。经过本人反复试验,总算找到比较好的解决方案,操作步骤如下
彻底解决Mac端git clone/push速度太慢的问题,详情请参阅文档。
jquery.clone
java中clone的详细用法,分浅拷贝和深拷贝,并分别有详细的实例介绍。从原理分析。
Clone Detection in Secure Messaging- Improving Post-Compromise Security in Practice
当项目很大,有一些很大的文件存在时,clone远程仓库代码可能会失败,clone下来的项目不完整,很可能是因为项目中的文件clone不全,这个工具可以解决这个问题
用 Java 语言编写的 初学者可学习的clone()
Jlink v8固件修复或解决Clone问题,内有固件下载地址。
详细的描述了Java中 clone方法使用
解决git clone时报错问题:sign_and_send_pubkey: signing failed: agent refused operation
arcgis Pro深度学习环境部署教程,clone一个名字为plam-detection的工程环境;clone的位置在C:\Users\admin\AppData\Local\ESRI\conda\envs可以去在Pro的project下切换环境。(安装完Pro后默认的conda的环境位置:C:...
Clone2Go DVD Ripper是强大的所有功能于一身的软件,使您可以轻松抓取DVD(包括CSS加密的DVD)和转换视频文件。 有了这个优秀的DVD Ripper,你可以快速翻录DVD到AVI,WMV,MP4,FLV,MOV,WMA,MP3,M4A,iTunes等等...