目录
一.基本数据类型的拷贝和引用类型的拷贝的区别
首先需要注意的是对于基本数据类型而言是没有深浅拷贝的区别。
1.基本类型的拷贝
2.引用类型的拷贝
对于深浅拷贝问题只是对于自定义类型而言,例如关于对象的拷贝,如果你直接拷贝,就相当于是浅拷贝。
二.关于Cloneable接口的使用和注意事项
1.Cloneable接口的使用
在该接口中没有clone()方法,该方法是在Object类中,但是我们不加该接口直接进行重写也会出现错误,该接口虽然没有抽象方法,但是在这里面相当于为一个标志,必须要加上。
2.clone()方法的重写
使用快捷键ctrl+o快速生成该方法
在生成该方法后有几个位置需要修改,首先将protected修改为public权限,接着将Object修改为本类名字,然后将返回值强转为本类类型。
修改后的结果如下:
@Override
public Demo clone() throws CloneNotSupportedException {
return (Demo) super.clone();
}
3.关于clone()的使用
关于异常的生成,使用快捷键alt+enter就可以显示出来
4.运行结果
5.验证clone()也为浅拷贝
6.关于浅拷贝的内存图解
7. 实现对象的深拷贝
虽然直接使用clone()为浅拷贝,我们可以对于该类中的引用类型一层一层的都实现Cloneable接口并重写clone()方法,直到最后一层只剩下基本类型,这样拷贝的就为深拷贝了。
(1)在本类中的拷贝方法中对引用类型进行拷贝
(2)结构图
(3)源代码
public class Demo implements Cloneable{
private int a=10;//基本类型
ShallowCopy sc;//引用类型
public Demo(){
sc=new ShallowCopy();//需要给引用类型创建对象,否则引用sc中的方法会出现空指针异常
}
@Override
public Demo clone() throws CloneNotSupportedException {
Demo demo = (Demo) super.clone();//将当前对象拷贝一份
demo.sc = sc.clone();//将当前对象中引用类型的对象拷贝一份
return demo;//返回拷贝好的对象
}
public static void main(String[] args) throws CloneNotSupportedException {
Demo demo1 = new Demo();
Demo demo2 = demo1.clone();//将demo1拷贝到demo2中
//修改demo2中的值,看是否对demo1中的值有影响
demo2.a=20;
demo2.sc.b=30;
demo2.sc.tp.c=50;
}
}
class ShallowCopy implements Cloneable{
int b=20;
TwoPiece tp;
public ShallowCopy(){
tp = new TwoPiece();
}
@Override
public ShallowCopy clone() throws CloneNotSupportedException {
ShallowCopy shallowCopy = (ShallowCopy) super.clone();
shallowCopy.tp = tp.clone();//需要将引用类型中的拷贝对象拷贝一份给当前对象中的引用类型
return shallowCopy;//将拷贝好的对象进行返回
}
}
//最后一层中成员变量只有基本类型
class TwoPiece implements Cloneable{
int c=40;
@Override
public TwoPiece clone() throws CloneNotSupportedException {
return (TwoPiece) super.clone();
}
}
三.总结
1.对于基本类型是不区分深浅拷贝,只有成员变量为引用类型时才会区分深浅拷贝。
2.对于Cloneable接口是没有clone()方法,该方法在Object类中,而所有的类都默认继承Object类,可以直阶对于该方法进行重写,但是还是要使用Cloneabel接口。
3.clone()进行拷贝还是浅拷贝,如果要实现深拷贝还需要对于每一个引用类型变量实现Cloneable接口。