深入分析java对象克隆

2023-05-16

目录

  • 1.什么是"克隆"?
  • 2.浅克隆与深克隆
  • 3.实现克隆的方法

1.什么是"克隆"?

由一个现有对象A,复制生成一个新的对象B的过程(B的初始值是由A对象确定的)。

  • 拷贝对象返回的是一个新对象,而不是一个引用。
  • 拷贝对象与用 new操作符返回的新对象的区别就是这个拷贝已经包含了一些原来对象的信息,而不是对象的初始信息。

2.浅克隆与深克隆

  • 浅拷贝的效果就是拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量和不可变引用变量(比如String类型属性))
  • 深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。

3.实现克隆的方法

  • 实现Cloneable
  1. 在要实现克隆的对象类中实现Cloneable接口

Cloneable接口为标记接口(标记接口为用户标记实现该接口的类具有该接口标记的功能,常见的标记接口有Serializable、Cloneable、RandomAccess),如果没有实现该接口,在调用clone方法时就会抛出CloneNotSupportException异常。

  1. 在类中重写Object的clone方法。

1.重写是为了扩大访问权限【Object类的clone方法使用protected【只有Object的同包和直接子类才可以访问】修饰】
2.为了实现深拷贝【Object的clone表现出来的是浅拷贝。对于可变的引用属性也使用clone方法,即递归调用clone即可实现深克隆】

  • 对象序列化

对象序列化也可以实现对象克隆,并且是深克隆,但是(序列化)串行化却很耗。

  1. 代码示例
//Teacher类
public class Teacher implements Serializable {
    private static final long serialVersionUID = 1L;
    String name;
    int age;
    Teacher (String name, int age) {
        this.name = name;
        this.age = age;
    }
  
//学生类        
public  class Student implements Serializable {
   private static final long serialVersionUID = 1L;
    String name;
    int age;
    Teacher t;
    Student (String name, int age, Teacher t) {
        this.name = name;
        this.age = age;
        this.t = t;
    }

    public Object deepClone() throws IOException, OptionalDataException,
            ClassNotFoundException {
        // 将对象写到流里(序列化)
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        ObjectOutputStream oo = new ObjectOutputStream(bo);
        oo.writeObject(this);
        // 从流里读出来(反序列化)
        ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
        ObjectInputStream oi = new ObjectInputStream(bi);
        return (oi.readObject());
    }
}

//测试类
public class TestDemo {

    /**
     * @param args
     */
    public static void main(String[] args) throws OptionalDataException,
            IOException, ClassNotFoundException {
        long t1 = System.currentTimeMillis();
        Teacher t = new Teacher("wangwu", 50);
        Student s1 = new Student("zhangsan", 18, t);
        Student s2 = (Student) s1.deepClone();
        s2.t.name = "lisi";
        s2.t.age = 30;
        System.out.println("name=" + s1.t.name + "," + "age=" + s1.t.age); // 学生1的教师不改变。
        long t2 = System.currentTimeMillis();
        System.out.println(t2-t1);
    }
}
  • BeanUtils.copyProperties
  1. spring的BeanUtils.copyProperties实现的浅克隆
  2. 如果要实现深克隆,需要对于引用属性也调用BeanUtils.copyProperties,即循环copy
  • 第三方框架

对象复制工具类,实现方法如下:

  1. 复制对象(深度拷贝)
  2. 复制集合(深度拷贝)
  3. 复制对象到指定类(深度拷贝)
  4. 复制集合到指定类(深度拷贝)
  1. 引入maven依赖
<!-- 对象拷贝 -->
<dependency>
    <groupId>uk.com.robust-it</groupId>
    <artifactId>cloning</artifactId>
    <version>1.9.12</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.47</version>
</dependency>
  1. 工具类
import com.alibaba.fastjson.JSON;
import com.rits.cloning.Cloner;
 
import java.util.ArrayList;
import java.util.List;
 

/**
 * Bean工具类
 * 
 */
public class BeanUtils {
 
    private static final Cloner cloner = new Cloner();
 
    /**
     * 复制对象(深度拷贝)
     * @param object
     * @param <T>
     * @return
     */
    public static <T> T clone(final T object){
        if (object == null) {
            return null;
        }
        return cloner.deepClone(object);
    }
 
    /**
     * 复制集合(深度拷贝)
     * @param object
     * @param <T>
     * @return
     */
    public static <T> List<T> cloneList(final List<T> object){
        if (object == null) {
            return null;
        }
        return cloner.deepClone(object);
    }
 
    /**
     * 复制对象到指定类(深度拷贝)
     * @param object
     * @param destclas 指定类
     * @param <T>
     * @return
     */
    public static <T> T clone(final Object object, Class<T> destclas){
        if (object == null) {
            return null;
        }
        String json = JSON.toJSONString(object);
        return JSON.parseObject(json, destclas);
    }
 
    /**
     * 复制集合到指定类(深度拷贝)
     * @param object
     * @param destclas 指定类
     * @param <T>
     * @return
     */
    public static <T> List<T> cloneList(List<?> object, Class<T> destclas) {
        if (object == null) {
            return new ArrayList<T>();
        }
        String json = JSON.toJSONString(object);
        return JSON.parseArray(json, destclas);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深入分析java对象克隆 的相关文章

  • 认识onNewIntent

    前几天面试被问到onNewIntent 我竟哑口无言 完全没听过这个东西 xff0c 所以总结经验教训 xff0c 多学习吧 一个简单的例子说明 xff1a activityA 启动activityB 并通过intent传递了一些数据 xf
  • 操作系统——作业

    写在前头 xff1a 这是小鱼上的网课整理来的笔记 xff0c 希望可以帮助大家更好的理解操作系统这门课 xff01 一 作业 这一讲 xff0c 我们来介绍作业的概念 我们需要从两个方面去理解作业 1 用户 我们可以先看看下面的图示的编译
  • 手把手教学在Springboot中搭建使用Guava cache,包教包会,不会我输一包辣条给你

    guava cache使用简介 概述 缓存是日常开发中经常应用到的一种技术手段 xff0c 合理的利用缓存可以极大的改善应用程序的性能 Guava官方对Cache的描述连接 缓存在各种各样的用例中非常有用 例如 xff0c 当计算或检索值很
  • Ubuntu使用Glmark2进行跑分

    Ubuntu使用Glmark2进行跑分 Glmark2 是一个基于 OpenGL 2 0 和 OpenGL ES 2 0 开发的benchmark程序 xff0c 主要用于对GPU的基准测试 安装和运行 Glmark2 安装依赖的开发工具
  • Ubuntu 22.04 安装Fcitx5中文输入法

    Ubuntu 22 04 安装Fcitx5中文输入法 一 检查系统中文环境 在 Ubuntu 设置中打开 区域与语言 管理已安装的语言 xff0c 然后会自动检查已安装语言是否完整 若不完整 xff0c 根据提示安装即可 二 安装Fcitx
  • AHU 2022 CTF新生赛web_writeup

    第一次当出题人 xff0c 给新生做的 xff0c 简简单单啦 按不了的F12 启动靶机 xff1a 根据题目名称可知 xff0c 这题与f12按键有关 xff0c 即查看网页源代码 按下f12发现f12按键被禁用 xff1a 尝试另一种方
  • 基于OpenAI实现的个人助理

    基于OpenAI实现的个人助理 最近OpenAI所开发的ChatGPT非常火 xff0c 于是我也去体验了一下 在玩过之余 xff0c 就想着能不能把它移植到系统环境 xff0c 成为一个日常的个人助理 xff0c 帮助我解决学习 开发或者
  • 基于OpenAI的Chatbot开发记录

    Chatbot 开发记录 最近ChatGPT非常火 xff0c 去体验之后确实有被惊艳到 xff0c 也对OpenAI上的人工智能模型比较感兴趣 xff0c 于是想着复刻一个ChatGPT xff0c 利用官方提供的包和api xff0c
  • 使用WebSocket实现异地同步看电影

    使用WebSocket实现异地同步看电影 项目地址 xff1a https github com Fangnan700 Film room 说明 放假回家之后 xff0c 因为和女朋友不在同一个地方 xff0c 又想着一起看电影 xff0c
  • 写一个AI小助手

    AI aides 本项目最初只是想对GPT 3模型进行一个封装 xff0c 后来发现了由 acheong08 大佬提供的接口 xff0c 于是将这个AI小助手进行了接入 xff0c 部署到服务器上后即可使用 本项目基于Python 和 un
  • 我在终端里养了个猫娘

    Kira 一个知识丰富且超级温柔的猫娘 x1f36d 食用指南 本项目是一个终端小程序 xff0c 智慧且温柔的猫娘Kira让你的终端不再单调乏味 第0步 在计算机合适的位置创建一个文件夹 xff0c 到本项目的release页面下载对应系
  • git pull命令的用法

    git pull用法 xff1a git pull命令的作用是 xff1a 取回远程主机某个分支的更新 xff0c 再与本地的指定分支合并 一句话总结git pull和git fetch的区别 xff1a git pull 61 git f
  • 《C++高效编程:内存与性能优化》第九章:高效内存管理

  • ubuntu安装chrome报错解决

    直接双击软件中心会报错 用命令安装也会报下面这个错 dpkg dependency problems prevent configuration of google chrome stable google chrome stable de
  • pycurl的学习之路

    pycurl的模块用法 c 61 pycurl span class hljs preprocessor Curl span span class hljs preprocessor 创建一个curl对象 span c span class
  • 如何在LINUX(UBUNTU)实现FTP服务器多用户多权限

    要求 实现两个用户 xff0c 使得一个student可以上传 xff0c 下载文件 另一个teacher可以上传 xff0c 下载 xff0c 删除文件 首先现在Ubuntu上安装ftp xff08 以下使用vsftp演示 xff09 1
  • TCP/IP:UDP(4) 缓存与抑制

    1 UDP协议 xff0c 发送方有一个虚拟的发送缓存区 假的 xff0c 意思是UDP应用程序生成数据报 xff0c 就直接发送出去 xff0c 不做任何处理 发送缓存区主要是限制单个数据报的大小 如果写一个太大的数据报 xff0c 内核
  • [Android Studio]android studio missing essential plugin

    出现问题 xff1a 在 Android Studio 中 disabled kotlin plugin 之后 xff0c 启动 Android studio 出现问题 android studio missing essential pl
  • vscode 统一格式化和eslint配置

    步骤 xff1a 1 安装并启用插件 xff1a editorConfig prettier eslint 2 安装所需依赖 3 在项目里配置vscode设置文件 4 在项目里配置editor prettier eslint 5 查看配置是
  • 用python爬取电影名,演员,评分等并存入excel

    1在python环境下找到安装python的路径 2在这个文件名后cmd 43 enter进入黑框 3在黑框中安装jupyter notebook 黑框中也可以安装其他python编辑是需要用的包 4创建一个学习python的文件夹 xff

随机推荐

  • El表达式与正则表达式

    第一次写博客 xff0c 主要用于总结知识 xff0c 有错的地方欢迎指教 EL表达式 EL表达式作用 xff1f 它使得jsp的Java代码变得简洁 jsp不能直接对隐式的对象属性进行操作 xff0c EL解决了这个问题 EL怎么用 xf
  • Error: `gyp` failed with exit code: 1

    Error 96 gyp 96 failed with exit code 1 解决方案 xff1a rm rf node gyp npm i g node gyp rm rf 项目地址 node modules npm install 参
  • css 设置 transform 无效

    在网上看到这句话 xff1a 因为transform只能转换由盒子模型定位的元素 经过测试发现 xff1a display值为block inline block grid table inline table 都可以 xff0c 总的来说
  • Android人脸与指纹识别

    基础人脸识别模块 添加依赖 请添加基本依赖 xff0c 不要添加 ktx 版本的依赖 xff0c 因为他需要 API33 及以上才可以使用 xff01 implementation 39 androidx biometric biometr
  • vue history模式下打包部署, node+express 刷新404

    解决这个问题可以使用中间件connect history api fallback xff0c 官方文档 xff1a https github com bripkens connect history api fallback 第一步 xf
  • element-ui单元格内容过长时省略号代替

    只要在需要设置的列加上 show overflow tooltip 61 39 true 39 即可 lt el table column prop 61 34 url 34 label 61 34 说明书下载地址 34 width 61
  • vue 页面保存成pdf

    安装插件 jspdf html2canvas npm install S jspdf npm install S html2canvas 使用 xff08 简单粗暴直接上 xff09 新建 htmlToPdf js 导出页面为PDF格式 i
  • 【Gauss】openGauss数据库ODBC环境连接配置(Windows)

    Windows操作系统自带ODBC数据源管理器 xff0c 无需用户手动安装管理器便可直接进行配置 实验环境 ECS xff08 openEuler ARM xff09 43 openGauss 操作步骤 1 下载客户端并进行安装 下载客户
  • 速看!2022年11月编程语言排行榜出炉!第一名太牛啦

    速看 xff01 2022年11月编程语言排行榜出炉 xff01 第一名太牛啦 每月更新一次的Tiobe编程排行榜来啦 xff01 快跟着肉肉一起看看11月的新看点吧 一 榜单情况 这里只展示排名靠前的前15名 xff1a TOP 10编程
  • 2022年12月编程语言排行榜,最新数据来了!

    2022年迎来了最后一个月 xff0c 也就是说新的一年马上就要到了 xff01 在这一年中编程语言起起伏伏 xff0c 有的语言始终炙手可热 xff0c 而有的语言却逐渐 没落 日前 xff0c 全球知名TIOBE编程语言社区发布了12月
  • angular模板加载

    angular模板加载 ng template Angularjs作为mvc xff08 或者说mvvm 框架 xff0c 同样具备模板这一基本概念 NG加载模板的顺序为 内存加载 AJAX加载 如果排版乱掉 xff0c 请查阅 https
  • 【HIVE】(四)数据导入/导出

    学习搬运工 xff0c 笔记摘自 实验楼课程 一 实验介绍 实验内容 Hive 数据的导入导出EXPORT 命令导出数据表或分区 xff0c 与元数据一起输出到指定位置 又可以从这个输出位置移动到不同的Hadoop 或Hive 实例中 xf
  • MySQL中的自增主键用完了怎么办

    目录 一场面试引发的血案 引发的问题 解决方案 扩展 目前业内在线修改表结构的方案 使用mysql5 6 43 提供的在线修改功能 借助第三方工具 改从库表结构 xff0c 然后主从切换 专业版回答 一场面试引发的血案 面试官 34 用过m
  • redis面试连环炮

    目录 Redis 的通讯协议是什么 Redis 究竟有没有 ACID 事务 Redis 的乐观锁 Watch 是怎么实现的 Redis 是如何持久化的 Redis 在内存使用上是如何开源节流 Redis 是如何实现主从复制 Redis 是怎
  • 一个字符串展现多种字体、字号、字体大小(NSAttributedString)

    NSAttributedString叫做富文本 xff0c 是一种带有属性的字符串 xff0c 通过它可以轻松的在一个字符串中表现出多种字体 字号 字体大小等各不相同的风格 xff0c 还可以对段落进行格式化 以下是实现代码 xff1a U
  • mybatis源码浅析①

    创建SqlSessionFactory 读取配置文件 Class getResource String path 1 path不以 39 开头时 xff0c 默认是从此类所在的包下取资源 xff1b 2 path 以 39 开头时 xff0
  • linux日志查看技巧

    版权声明 xff1a 本文为博主原创文章 xff0c 遵循 CC 4 0 BY SA 版权协议 xff0c 转载请附上原文出处链接和本声明 本文链接 xff1a https blog csdn net zw235345721 article
  • Ubuntu杀手锏命令

    常用命令 Ubuntu GNOME快捷键 Ctrl 43 Alt 43 T xff08 打开GNOME终端窗口 xff09 Alt 43 F1 显示所有应用窗口 类似Windows中 Alt 43 Tab Alt 43 F2 运行程序快捷键
  • 线程之我见(一)

    目录 概念线程状态NEW xff08 初始状态 xff09 定义实例 RUNNABLE xff08 就绪 执行中状态 xff09 定义实例 BLOCKED xff08 阻塞状态 xff09 定义实例 概念 是操作系统能够进行运算调度的最小单
  • 深入分析java对象克隆

    目录 1 什么是 34 克隆 34 xff1f 2 浅克隆与深克隆3 实现克隆的方法 1 什么是 34 克隆 34 xff1f 由一个现有对象A xff0c 复制生成一个新的对象B的过程 B的初始值是由A对象确定的 拷贝对象返回的是一个新对