Java中对象的序列化方式克隆详解

Java中对象的序列化方式克隆详解

什么是对象的序列化?

在Java中,对象的序列化是指将Java对象转换为二进制流的过程。序列化可以将对象存储在文件或者在网络传输中进行传输,也可以通过反序列化将二进制流转换为Java对象。

Java中提供了java.io.Serializable接口,如果一个类实现了这个接口,则该类的对象可以被序列化。

Java中的序列化实现

Java中的序列化实现由系统提供,我们可以通过以下代码将一个Java对象序列化:

public static void serialize(Object obj, File file) throws IOException {
    try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file))) {
        oos.writeObject(obj);
    }
}

上面代码的serialize方法接收一个Java对象和一个文件路径作为参数,将该Java对象序列化并存储到指定路径下的文件中。

Java中的反序列化实现

Java中的反序列化实现也由系统提供,我们可以通过以下代码将一个二进制流反序列化为Java对象:

public static Object deserialize(File file) throws IOException, ClassNotFoundException {
    try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
        return ois.readObject();
    }
}

上面代码的deserialize方法接收一个存储了Java对象序列化结果的文件路径,并将其反序列化为Java对象。

对象的克隆

当我们需要复制一个Java对象时,我们可以使用对象的序列化和反序列化实现对象的克隆。

下面是一个示例,使用对象的序列化和反序列化实现对象的克隆:

public static Object clone(Object obj) throws IOException, ClassNotFoundException {
    //将对象序列化到byte[]数组中
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    try (ObjectOutputStream oos = new ObjectOutputStream(bos)) {
        oos.writeObject(obj);
    }
    //将byte[]数组反序列化为对象
    ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
    try (ObjectInputStream ois = new ObjectInputStream(bis)) {
        return ois.readObject();
    }
}

示例1

下面是一个示例,将一个Java对象序列化并存储在文件中,然后再将文件中的二进制流反序列化为Java对象:

public static void main(String[] args) throws IOException, ClassNotFoundException {
    Person person = new Person("小明", 18);
    File file = new File("person.ser");
    //将对象序列化到文件中
    serialize(person, file);
    //将文件中的二进制流反序列化为Java对象
    Person clonePerson = (Person) deserialize(file);
    //打印克隆的对象
    System.out.println(clonePerson);
}

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

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

运行以上代码,输出结果为:

Person{name='小明', age=18}

示例2

下面是另一个示例,将一个Java对象序列化并存储在文件中,然后再通过对象的克隆实现对象的深度复制:

public static void main(String[] args) throws IOException, ClassNotFoundException {
    Address address = new Address("中国", "北京", "朝阳区");
    Person person = new Person("小明", 18, address);
    File file = new File("person.ser");
    //将对象序列化到文件中
    serialize(person, file);
    //深度复制
    Person clonePerson = (Person) clone(person);
    clonePerson.getAddress().setCity("上海");
    //打印克隆的对象和原对象的地址信息,验证是否实现了深度复制
    System.out.println(person.getAddress().getCity());
    System.out.println(clonePerson.getAddress().getCity());
}

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;
    }

    public Address getAddress() {
        return address;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address=" + address +
                '}';
    }
}

static class Address implements Serializable {
    private String country;
    private String city;
    private String district;

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

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public String toString() {
        return "Address{" +
                "country='" + country + '\'' +
                ", city='" + city + '\'' +
                ", district='" + district + '\'' +
                '}';
    }
}

运行以上代码,输出结果为:

朝阳区
上海

从输出结果可以看到,对象的克隆实现了深度复制,克隆对象和原对象地址信息已经不同。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java中对象的序列化方式克隆详解 - Python技术站

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

相关文章

  • 什么是线程状态?

    以下是关于线程状态的完整使用攻略: 什么是线程状态? 线程状态是指线程在不同的执行阶段处的状态。在 Java 中,线程状态主要有以下几种: 新建状态(New):当线程对象被创建时,它处于新建状态。 就状态(Runnable):当线程对象调用 start() 方法后,它处于就绪状态,等待系统分配 CPU 时间片。 运行状态():当线程获得 CPU 时间片后,它…

    Java 2023年5月12日
    00
  • spring jdbctemplate的用法小结

    下面是关于“spring jdbctemplate的用法小结”的完整攻略。 Spring JdbcTemplate的用法小结 概述 Spring JdbcTemplate是Spring框架提供的一个数据访问工具,用于简化JDBC编程。它封装了JDBC API并且提供了一些方便的方法,使得我们可以更加便捷地进行数据库操作。 使用步骤 使用Spring Jdbc…

    Java 2023年5月20日
    00
  • Java压缩文件操作详解

    非常感谢您来到我们的网站!我很高兴能为您提供有关“Java压缩文件操作详解”的完整攻略。 一、概述 在Java编程中,处理大量的文件和文件夹是一个很常见的需求。为了方便和提高效率,许多时候我们需要对多个文件或文件夹进行压缩,将它们打包成一个文件,以减少文件的数量和占用空间。 Java提供了很多操作压缩文件的类和方法,其中最常用的是 java.util.zip…

    Java 2023年5月20日
    00
  • 基于mybatis查询结果映射不到对象的处理

    当使用MyBatis查询数据时,有时候会遇到查询结果映射不到对象的情况。这可能是由于数据库中的列名与实体类中的属性名不匹配等原因导致的。下面是基于MyBatis查询结果映射不到对象的处理攻略: 1.查询结果列名与实体类属性名不匹配 如果查询结果中的列名与实体类中的属性名不匹配,那么MyBatis就无法自动将查询结果映射到相应的属性中。此时,我们可以使用别名来…

    Java 2023年5月20日
    00
  • 用java代码帮朋友P图

    下面是“用java代码帮朋友P图”的完整攻略: 准备工作 首先,我们需要安装并配置好Java开发环境。建议使用JDK1.8及以上版本,可以到Oracle官网下载并安装。安装完成后,需配置Java环境变量,具体可参考官方文档或搜索教程进行配置。 图像处理库 Java提供了许多用于图像处理的库,常用的有Java2D和JavaFX等。这里我们选择Java2D,它提…

    Java 2023年5月23日
    00
  • spring security自定义认证登录的全过程记录

    下面是关于“spring security自定义认证登录的全过程记录”的详细攻略: 背景 Spring Security是Spring家族中重要的一员,主要用于Web应用的安全框架。它可以实现对应用的URL、方法和资源进行保护,在身份验证和授权方面提供了全面的支持。其中认证是指确认用户身份,而授权是指决定用户可以访问系统哪些资源。Spring Securit…

    Java 2023年5月19日
    00
  • Java加密解密和数字签名完整代码示例

    首先我们需要明确几个概念:加密、解密、数字签名。 加密:将明文(未加密的数据)通过某种方式转换成密文(已加密的数据),使得未授权的第三方无法读取到数据内容。 解密:将密文还原成明文,使得有授权的第三方可以读取数据内容。 数字签名:对数据进行加密后再生成一个签名,用于验证数据的来源和完整性。 下面我们分别讲解 Java 中的加密解密和数字签名的完整代码示例。 …

    Java 2023年5月19日
    00
  • Java Class.forName()用法和newInstance()方法原理解析

    Java中的Class对象提供了一些强大的机制来处理编译时期未知的类,比如在运行时动态加载并实例化一个类。其中Class.forName()和newInstance()方法是两个非常重要的方法,本文将详细讲解它们的用法和原理。 Java Class.forName()方法 Class.forName()是Java反射机制中的核心方法之一,它可以根据类名动态加…

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