1.深浅克隆定义
Java 中的数据类型分为基本数据类型和引用数据类型。对于这两种数据类型,在进行赋值操作、用作方法参数或返回值时,会有值传递和引用(地址)传递的差别。
(补充)基本数据类型包括byte,short,int,long,float,double,boolean,char 8种;
浅度克隆:被克隆得到的对象基本类型的值修改了,原对象的值不会改变
深度克隆:被克隆得到的对象基本类型的值修改了,原对象的值改变
2.代码实现
2.1浅克隆实现
public class ShadowClone implements Cloneable {
private int a; // 基本类型
private int[] b; // 非基本类型
// 重写Object.clone()方法,并把protected改为public
@Override
public Object clone(){
ShadowClone sc = null;
try
{
sc = (ShadowClone) super.clone();
} catch (CloneNotSupportedException e){
e.printStackTrace();
}
return sc;
}
public int getA()
{
return a;
}
public void setA(int a)
{
this.a = a;
}
public int[] getB() {
return b;
}
public void setB(int[] b) {
this.b = b;
}
}
测试
ShadowClone c1 = new ShadowClone();
//对c1赋值
c1.setA(100) ;
c1.setB(new int[]{1000}) ;
System.out.println("克隆前c1: a="+c1.getA()+" b="+c1.getB()[0]);
//克隆出对象c2,并对c2的属性A,B,C进行修改
ShadowClone c2 = (ShadowClone) c1.clone();
//对c2进行修改
c2.setA(50) ;
int []a = c2.getB() ;
a[0]=500 ;
c2.setB(a);
System.out.println("克隆前c1: a="+c1.getA()+" b="+c1.getB()[0]);
System.out.println("克隆后c2: a="+c2.getA()+ " b[0]="+c2.getB()[0]);
克隆前c1: a=100 b=1000
克隆前c1: a=100 b=500
克隆后c2: a=50 b[0]=500
2.2深克隆实现
2.2.1重写Clone方法
class bottle implements Cloneable {
public wine wn;
public bottle(wine wn) {
this.wn = wn;
}
// 覆写clone()方法
@Override
protected Object clone() throws CloneNotSupportedException {
bottle newBtl = (bottle) super.clone();
newBtl.wn = (wine) wn.clone();
return newBtl;
}
}
class wine implements Cloneable {
int degree;
public int getDegree() {
return degree;
}
public void setDegree(int degree) {
this.degree = degree;
}
// 覆写clone()方法
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
测试
public static void main(String[] args) throws CloneNotSupportedException {
bottle bottle = new bottle(new wine());
bottle bottle1 = (bottle) bottle.clone();
System.out.println("bottle1.wine : " + bottle1.wn.getDegree() );
bottle1.wn.setDegree(100);
System.out.println("bottle1.wine : " + bottle1.wn.getDegree() );
System.out.println("bottle.wine : " + bottle.wn.getDegree());
}
bottle1.wine : 0
bottle1.wine : 100
bottle.wine : 0
2.2.2序列化实现
class DeepPerson implements Serializable {
private int a;
private int[] b;
public DeepPerson() {
}
public DeepPerson(int a, int[] b) {
this.a = a;
this.b = b;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public int[] getB() {
return b;
}
public void setB(int[] b) {
this.b = b;
}
}
class Test1 {
public static void main(String[] args) throws CloneNotSupportedException{
DeepPerson dc1 = new DeepPerson();
// 对dc1赋值
dc1.setA(100);
dc1.setB(new int[] { 1000 });
System.out.println("克隆前dc1: a=" + dc1.getA()+"b[0]=" + dc1.getB()[0]);
DeepPerson dc2 = (DeepPerson) deepClone(dc1);
// 对c2进行修改
dc2.setA(50);
int[] a = dc2.getB();
a[0] = 500;
System.out.println("克隆后dc1: a=" + dc1.getA()+"b[0]=" + dc1.getB()[0]);
System.out.println("克隆后dc2: a=" + dc2.getA()+"b[0]=" + dc2.getB()[0]);
}
public static Object deepClone(Object object){
Object o=null;
try{
if (object != null){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
oos.close();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
o = ois.readObject();
ois.close();
}
} catch (IOException e){
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return o;
}
}
测试
克隆前dc1: a=100b[0]=1000
克隆后dc1: a=100b[0]=1000
克隆后dc2: a=50b[0]=500
【参考】
https://blog.csdn.net/qq_41967563/article/details/104974789
https://www.jianshu.com/p/f52e5165222a