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("深度克隆成功");
        }
    }
}

结果:

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

java中实现对象的深度克隆相关推荐

  1. linux hashmap,Java中对HashMap的深度分析与比较

    Java中对HashMap的深度分析与比较 在Java的世界里,无论类还是各种数据,其结构的处理是整个程序的逻辑以及性能的关键.由于本人接触了一个有关性能与逻辑同时并存的问题,于是就开始研究这方面的问 ...

  2. Java中的对象类型像引用还是指针,谁是谁非?

    Java中的对象类型像引用还是指针,谁是谁非? 作者:海枫 地址:http://blog.csdn.net/linyt 作为一名程序员,我们应该对新知识和新技术刨根问底,而不应泛泛而谈.我未曾接触到J ...

  3. 【性能优化】面试官:Java中的对象和数组都是在堆上分配的吗?

    写在前面 从开始学习Java的时候,我们就接触了这样一种观点:Java中的对象是在堆上创建的,对象的引用是放在栈里的,那这个观点就真的是正确的吗?如果是正确的,那么,面试官为啥会问:"Jav ...

  4. java中String对象和String变量

    2019独角兽企业重金招聘Python工程师标准>>> java中String对象和String变量 (2011-12-27 20:40:27) 转载▼ 标签: it 最近在论坛上看 ...

  5. Java中的对象序列化操作

    文章目录 1 Java中的对象序列化操作 1 Java中的对象序列化操作 首先看一下对象序列化的操作步骤: 创建一个类,继承Serializable接口 创建对象 将对象写入文件 从文件读取对象信息 ...

  6. 【译】Java中的对象序列化

    前言 好久没翻译simple java了,睡前来一篇. 译文链接: http://www.programcreek.com/2014/01/java-serialization/ 什么是对象序列化 在 ...

  7. Java中,一切皆是对象——java中的对象类型与基本数据类型的区别

    起因:取一个list给另一个list赋值,然后在另一个list中取出进行修改.list其中类型为对象时,String时,基本数据类型时. [java中的对象类型与基本数据类型的区别] #声明和实例化 ...

  8. java中String对象作为参数传递问题

    问题 java中将对象作为参数传递究竟是值传递还是引用传递? 1.基本类型作为参数传递时,是传递值的拷贝,无论你怎么改变这个拷贝,原值是不会改变的. 2.对象作为参数传递时,是把对象在内存中的地址拷贝 ...

  9. java 监控对象是什么_多线程-Java中的对象监视器是什么意思? 为什么要使用这个词?...

    多线程-Java中的对象监视器是什么意思? 为什么要使用这个词? 在阅读有关Java线程的文章时,我经常注意到这样的表达:"当前线程是该对象的监视器的所有者". 我的意思是:线程有 ...

最新文章

  1. 文巾解题 319. 灯泡开关
  2. MyBatis处理多参数及原理分析
  3. Struts2.perperties中的配置详解
  4. 一个可变布局列表,有9种布局item大小,每个item可拖拽切换位置
  5. 一文总结More Effective c++
  6. Qt——P10 自定义的信号和槽
  7. 2018/3/9 省选模拟赛 0分
  8. DB2安装到卸载一套龙服务
  9. 【阿里云-如何实现实名认证】
  10. 训练好的vgg报错RuntimeError:mat1 and mat2 shapes cannot be multiplied(512*49 and 25088*4096)
  11. Android开发唯一的出路:进阶学习,android实战pdf
  12. 大数据学习一般都需要学习哪些知识
  13. 金仓数据库KingbaseES客户端编程接口指南-ODBC(6. KingbaseES ODBC 的扩展属性)
  14. 使用PostgreSQL 9.6 架设mediawiki服务器
  15. URL详细分析及在python中处理URL
  16. 微信小程序开发 01
  17. 贾樟柯监制X水井坊呈现,微电影《以桌·会友》
  18. 【数分书单】分析思维《一本小小的蓝色逻辑书》第一/二章小结
  19. 《超级精灵球》6.16正式上线链游玩家 | 超酷萌宠、经典再现
  20. 微信小程序·前端-锦囊

热门文章

  1. java 计算向量cos距离_欧氏距离和cos相似度
  2. 多因子认证是什么意思?与双因子认证有什么区别?
  3. 易语言POST专题-GET POST 区别详解
  4. 翻转英文句子中单词的顺序
  5. 六年级计算机考试总结,关于六年级考试总结
  6. 数据分析面试【概率论与统计学】总结之-----统计学常见面试题整理
  7. 大恶人吉日嘎拉之走火入魔闭门造车之.NET疯狂架构经验分享系列之(四)高效的后台权限判断处理
  8. 缓冲区、着色器和HLSL
  9. KB Kb kB 大小写的区别
  10. 【IDEA】TKK: 更新 TKK 失败,请检查网络连接