1、引言
我们在学习的数组时,就了解到了数组克隆方法,可以通过数组克隆方法来拷贝一个一模一样的数组:
那对于自定义类型中有没有克隆方法呢?答案是有的!
就让这篇文章来帮助大家学习自定义类型的拷贝!
2、自定义类型的拷贝
我们首先自定义一个学生类:
我们已知,所有的类都继承于Object类,我们可以看到Object类中也实现了clone方法:
按理说,作为子类是可以使用继承下来的clone方法的,可是当我们去使用clone方法时却发现写不出来:
那我们该如何去实现自定义类型的拷贝呢?
1. 重写clone方法
为什么要重写clone方法呢?我们先来看Object类中的clone方法:
我们发现父类中方法的权限是protected,那我们就需要利用super关键字来调用父类的clone方法,所以我们重写clone方法:
这时我们发现我们已经可以写出了clone方法:
可是代码仍然报错,那是因为方法的返回值是Object类型:
2. 强制类型转换为子类类型
我们发现仍然报错,那是因为我们没有抛出异常。
3. 抛出异常
我们可以发现,在我们利用Idea快速重写了clone方法后,重写方法抛出了异常:
那我们也需要在main方法抛出异常:
我们这时发现,没有了报错,那我们来运行:
却出现了不支持克隆的异常,因为我们还差最后一步,实现Cloneable接口
4. 实现Clonable接口
当我们点进去查看这个接口时,我们发现什么方法都没有:
这表面,Cloneable是一个空接口,
那有人就有疑问了:“什么都没有那空接口是来干嘛来了?”
答:空接口也叫做标记接口,表示当前类是可以被克隆的!!!
总结步骤:
1. 重写clone方法
2. 强制类型转换为子类类型
3. 抛出异常
4. 实现Clonable接口
在完成以上步骤后,我们就可以成功的拷贝出一个对象:
3、浅拷贝
当我们在自定义Student类中再定义一个自定义类的对象后,
我们再次进行拷贝,并修改拷贝的student2对象的moneyNum值,我们会发现,student1的moneyNum也被改变了:
这是因为,原有的student1和拷贝后的student2中的money引用指向的是同一个区域,只要一个改变,另外一个就会跟着改变,我们可以参考下图理解:
我们并没有把Money对象中的moneyNum也拷贝一份,
也就是说,我们只拷贝了Student对象,而没有拷贝Money对象,这样的拷贝称为浅拷贝!!!
那如何做到修改student2的moneyNum值而不影响student1中的moneyNum值呢?
答:那就需要完成深拷贝。
4、深拷贝
其实完成深拷贝也是很简单的,我们只需要额外的完成对Money的拷贝就可以了,
为了完成对自定义类型Money的拷贝,也需要根据上面讲到的步骤完成(在此不再列出细节):
然后,我们只需在Student类中重写的clone方法上做处理即可:
(我们将浅拷贝得到的tmp中Money对象也完成一份拷贝即可)
这时我们发现,修改student2的moneyNum值便不会影响到student1了,也就是说,我们成功的将Money对象也拷贝了一份,完成了深拷贝!!!
OK~本次博客到这里就结束了,
感谢大家的阅读~欢迎大家在评论区交流问题~
如果博客出现错误可以提在评论区~
创作不易,请大家多多支持~