Java深浅克隆原理及实现

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wimb

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值