Java 对象深拷贝工具类的实现

概述:

Java 对象深拷贝是指将一个对象完全复制另一个对象,即所有属性和属性值都被复制,并且两个对象之间没有相互影响。在 Java 开发中经常会使用对象深拷贝,比如在进行对象传参、克隆等场合都需要进行对象深拷贝。本文将详细讲解 Java 对象深拷贝工具类的实现。

实现:

Java 中提供了两种方式实现深拷贝:Serializable 和 Cloneable,下面分别进行介绍。

  1. Serializable 方式实现深拷贝

Serializable 序列化方式实现深拷贝,需要实现 Serializable 接口,并在对象的 writeObject 和 readObject 方法中进行序列化和反序列化。示例如下:

import java.io.*;

public class DeepCopyUtil {

    public static <T> T deepCopy(T t) throws Exception {
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        ObjectOutputStream oo = new ObjectOutputStream(bo);
        oo.writeObject(t);

        ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
        ObjectInputStream oi = new ObjectInputStream(bi);
        return (T) oi.readObject();
    }

    static class Person implements Serializable {
        private String name;
        private int age;
        private Address address;

        public Person(String name, int age, Address address) {
            this.name = name;
            this.age = age;
            this.address = address;
        }
    }

    static class Address implements Serializable {
        private String city;
        private String street;
    }

    public static void main(String[] args) throws Exception {
        Address address = new Address();
        address.city = "Beijing";
        address.street = "Chang'an Street";
        Person originPerson = new Person("Tom", 20, address);
        Person copyPerson = deepCopy(originPerson);
        System.out.println(copyPerson == originPerson);
        System.out.println(copyPerson.address == originPerson.address);
    }
}

输出结果:

false
false

从输出结果可以看出,通过 Serializable 方式实现深拷贝,对象被完全复制,两个对象没有相互影响,即使是对象中的属性也被完全复制。

  1. Cloneable 方式实现深拷贝

Cloneable 克隆方式实现深拷贝,需要将对象实现 Cloneable 接口,并在对象的 clone 方法中进行克隆。示例如下:

public class DeepCopyUtil {

    public static <T extends Cloneable> T deepCopy(T t) throws Exception {
        Method method = t.getClass().getDeclaredMethod("clone");

        @SuppressWarnings("unchecked")
        T copy = (T) method.invoke(t);
        return copy;
    }

    static class Person implements Cloneable {
        private String name;
        private int age;
        private Address address;

        public Person(String name, int age, Address address) {
            this.name = name;
            this.age = age;
            this.address = address;
        }

        public Person clone() throws CloneNotSupportedException {
            Person person = (Person) super.clone();
            person.address = address.clone();
            return person;
        }
    }

    static class Address implements Cloneable {
        private String city;
        private String street;

        public Address(String city, String street) {
            this.city = city;
            this.street = street;
        }

        public Address clone() throws CloneNotSupportedException {
            return (Address) super.clone();
        }
    }

    public static void main(String[] args) throws Exception {
        Address address = new Address("Beijing", "Chang'an Street");
        Person originPerson = new Person("Tom", 20, address);
        Person copyPerson = deepCopy(originPerson);
        System.out.println(copyPerson == originPerson);
        System.out.println(copyPerson.address == originPerson.address);
    }
}

输出结果:

false
false

从输出结果可以看出,通过 Cloneable 方式实现的深拷贝,对象也被完全复制,两个对象没有相互影响。

总结:

Java 对象深拷贝工具类的实现有多种方式可供选择,本文给出了两种方式,即 Serializable 和 Cloneable 方式。其中 Serializable 方式更加通用,但效率较低,而 Cloneable 方式效率较高,但需要实现 clone 方法,这对于一些已有类可能是不可行的。因此,在实际开发中,开发者需根据实际情况选择最合适的方式进行实现。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java 对象深拷贝工具类的实现 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • MyBatis-Plus框架整合详细方法

    当我们将Spring Boot和MyBatis框架结合时,通常使用MyBatis-Plus作为MyBatis框架的扩展库。MyBatis-Plus简化了MyBatis的常见操作,使开发人员更轻松地完成数据访问层的开发。在下面的攻略中,我将会为大家讲解根据MyBatis-Plus官方文档整合MyBatis-Plus框架的详细方法。 1. 添加Maven依赖 在…

    Java 2023年5月20日
    00
  • Java 编程之IO流资料详细整理

    Java 编程之IO流资料详细整理 什么是 IO 流 输入输出流(IO流)指的是一种提供了对数据流进行读写的机制,是 Java 中用于处理流数据的一种常用方式。在 Java 中,IO 流分为字节流和字符流两种方式,分别处理二进制数据和文本数据。 IO 流的分类 字节流 字节流是 IO 流中最基本的一种,主要用于处理二进制数据。Java 中的字节流有两个基本的…

    Java 2023年5月23日
    00
  • JavaEE实现前后台交互的文件上传与下载

    下面我将详细讲解“JavaEE实现前后台交互的文件上传与下载”的完整攻略。 1. 前言 在Web开发中,文件上传和下载是比较常见的需求,在JavaEE中实现文件上传和下载的过程也不复杂,只需要使用一些相关的API和技术即可完成。本文将分享实现JavaEE中文件上传和下载的详细过程及相关示例,帮助读者了解JavaEE中的文件操作。 2. 文件上传 2.1 文件…

    Java 2023年5月19日
    00
  • SpringBoot实战教程之新手入门篇

    SpringBoot实战教程之新手入门篇攻略 SpringBoot是一种快速开发、简化配置的Java框架。它集成了常用的开发工具,如SpringMVC、Hibernate、MyBatis等,能够帮助开发人员快速搭建Java Web项目。本篇攻略将介绍学习SpringBoot的入门教程。 1. 安装Java和IDE 在开始学习SpringBoot之前,需要先安…

    Java 2023年5月15日
    00
  • 关于Struts2文件上传与自定义拦截器

    关于Struts2文件上传与自定义拦截器的完整攻略 文件上传 环境配置 在使用Struts2进行文件上传之前,需要进行相关的环境配置。首先需要在struts.xml文件中配置org.apache.struts2.dispatcher.multipart.MultiPartRequest类型的解析器: <constant name="strut…

    Java 2023年5月20日
    00
  • 如何在Spring Boot应用中优雅的使用Date和LocalDateTime的教程详解

    如何在Spring Boot应用中优雅的使用Date和LocalDateTime的教程详解 Spring Boot作为一个常用的Java Web框架,经常需要用到日期类型,例如在处理用户操作记录、日志记录、订单生成等业务中。本文将介绍在Spring Boot应用中如何优雅地使用Date和LocalDateTime类型。 Date类型 1. Date类型的创建…

    Java 2023年5月20日
    00
  • java发送http的get、post请求实现代码

    下面是Java发送HTTP的GET、POST请求实现代码的完整攻略,包含两条示例说明。 准备工作 在使用Java发送HTTP请求前,需要导入相关包和类库。Java提供了两种发送HTTP请求的方式:URLConnection和HttpClient。我们可以根据实际的需求选择使用不同的方法。 1. 使用URLConnection发送HTTP请求 使用URLCon…

    Java 2023年5月30日
    00
  • PHP一些有意思的小区别

    当我们在使用PHP进行开发的时候,可能会遇到一些有趣的小区别,这些小区别可能不会影响代码的运行,但是了解这些区别可以让我们更全面地理解PHP语言。下面是一些例子: 单引号和双引号 在PHP中,单引号和双引号用于定义字符串,二者有所不同。单引号中的文本会被原样输出,而双引号中的文本会被解析并替换掉其中的变量。例如: $name = "Tom&quot…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部