java中实现对象的深度克隆

1.什么是深度拷贝和浅拷贝       

       python中有深度拷贝(也可以叫深度克隆)和浅拷贝,同样在java中很多时候需要深度拷贝对象,所谓的深度拷贝对象指的就是对于对象的所用数据及其全部进行copy一份,变成两个完全不相关的对象,而浅拷贝不拷贝对象所用的数据资源等,虽是两个不同的参数标识符,但是用的是同一个数据对象,也就是用‘==’,这是浅拷贝。也就是C语言中形容的指针指向的物理存储区域对象其实是一个。

      带来的问题:浅拷贝无论你通过任何浅拷贝的对象修改其值,最后的其他的对象都会被改变,相信我,这是一个很常见的坑。

2.java对象的深度拷贝

        其实java中的很多对象已经实现了深度拷贝,比如说map中的putAll(),但是需要实现自己创建的对象的深度拷贝呢,山不转水转,总会碰到的。

       下面来说明一下java中的深度拷贝,其最佳的方式就是实现Serializable接口,用序列化和反序列化来实现对象的深度拷贝,所谓的序列化和反序列化简单说明下,序列化指的就是把对象直接转化成文件或者其他持久层数据(二进制文件,字节码文件),反序列化指的就是读出该数据,重新建立对象的过程。因为java中的JVM虚拟机是有生命周期的,所以说任何对象的生命周期不会超过当前的JVM虚拟机的生命周期,所以需要序列化和反序列化,解决办法就是给其Serializable中有一个ID值,是不是原来一看到别人写的Serializable就不知道东南西北了,这个表示的就是版本号,防止错乱嘛。下面来介绍一下java对象的深度克隆。

3.java中的实现及其原理分析

       java中的对象的深度克隆主要的原理就是实现对象的字节流转换,然后在把当前的字节流对象输出,得到新的对象。代码:

public Object deepClone() {
            try {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();//字节流对象
                ObjectOutputStream oos = new ObjectOutputStream(bos);//开始转换该对象
                oos.writeObject(this);//写到当前类,当然也可以写入文件
                ByteArrayInputStream bais = new ByteArrayInputStream(bos.toByteArray());//字节输出流
                ObjectInputStream ois = new ObjectInputStream(bais);//输出该对象
                return (Object) ois.readObject();//读出对象,实现新对象的生成
            } catch (Exception e) {
                System.out.println("克隆出错"+e.getStackTrace());
                return null;
            }
        }
    }

4.测试结果代码

原理实际上非常的简单,下面来测试一下,完整的代码:

package java_test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;


public class study implements Serializable{
    private static final long serialVersionUID = 1L;
    public static  int arr[] = {1,2};
    
    public static class class1 {//内部类,也是我们克隆的对象

        public Object deepClone() {
            try {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(bos);
                oos.writeObject(this);
                ByteArrayInputStream bais = new ByteArrayInputStream(bos.toByteArray());
                ObjectInputStream ois = new ObjectInputStream(bais);
                return (Object) ois.readObject();
            } catch (Exception e) {
                System.out.println("克隆出错"+e.getStackTrace());
                return null;
            }
        }
    }
    
    public static void main(String[] args) {//验证一下克隆前和克隆后是不是一个对象
        class1 c = new class1();
        Object c2 = c;
        if (c == c2){
            System.out.println("克隆前c和出c2相等,也就是c和c2其实是一个对象!");
        }else{
            System.out.println("克隆前c和出c2不相等,出现理论不符合逻辑错误!");
        }
        c2 = c.deepClone();
        
        if (c == c2){
            System.out.println("深度克隆失败");
        }else{
            System.out.println("深度克隆成功");
        }
    }
}

结果:

测试程序,本文观点来自个人理解,有不足之处请之处,希望不吝赐教。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值