JAVA序列化和反序列化的底层实现原理解析

JAVA序列化和反序列化的底层实现原理解析

序列化与反序列化的概念

序列化

序列化是指将对象转换成可传输的格式(例如字节码),并且可以在将来重新创建出与原对象完全相同的副本。序列化操作可以在网络上传输对象,或者将对象存储到本地磁盘上。

反序列化

反序列化是指将序列化后的数据流还原为原来的对象的操作。也就是说,反序列化能够重新创建出一个和已序列化的对象完全相同的对象实例。

序列化原理

序列化的实现

Java 序列化由 ObjectOutput 和 ObjectOutputStream 两部分组成。

具体来讲,ObjectOutput 在写出对象前会先写出该对象的 MetaData,即对象类型信息和属性值信息,然后使用 java.io.Serializable 接口中的 writeObject 方法将实例对象写入输出流中。

而 ObjectOutputStream 实现了 ObjectOutput 接口,在序列化时也采用了写出 MetaData 和 对象信息的方式,但在写出 MetaData 时,对同一类型的 MetaData 只创建一个。在写出对象时,该对象的类型信息和之前已写出的类型信息进行匹配,如果找到相同的类型信息,就使用之前的 MetaData,否则就新创建一个 MetaData 并记录下来。

序列化的缺点

Java 序列化存在以下缺点:

  1. 序列化后的数据量大,序列化后的码流默认为二进制编码,体积较大,不利于网络传输。
  2. 序列化运行效率较低,可能会影响系统的性能。
  3. 序列化后的数据不便于人阅读。

反序列化原理

反序列化可以使用 ObjectInput 和 ObjectInputStream 实现。

ObjectInput 接口有一个 readObject 方法,可以将序列化后的数据流反序列化成相应的对象。与序列化类似,反序列化时也需先读取定制化的 MetaData,根据 MetaData 对读入的二进制序列化数据进行解码,并转化为实例对象。

同时,ObjectInputStream 可以通过 setAllowList() 方法设置反序列化时允许读取的类白名单或黑名单,以防止序列化漏洞。

示例说明

以下是一个序列化示例:

public class User implements Serializable {
    String name;
    int age;

    // 省略构造函数和 Getter/Setter 方法

    public static void main(String[] args) throws IOException {
        FileOutputStream fileOut = new FileOutputStream("user.ser");
        ObjectOutputStream out = new ObjectOutputStream(fileOut);

        User user = new User("Jack", 18);
        out.writeObject(user);

        out.close();
        fileOut.close();
    }
}

该代码片段将 User 对象序列化到 user.ser 中。

以下是一个反序列化示例:

public class User implements Serializable {
    String name;
    int age;

    // 省略构造函数和 Getter/Setter 方法

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        FileInputStream fileIn = new FileInputStream("user.ser");
        ObjectInputStream in = new ObjectInputStream(fileIn);

        User user = (User) in.readObject();

        in.close();
        fileIn.close();
    }
}

该代码片段从 user.ser 中读出序列化后的 User 对象,并将其反序列化为 Java 对象实例。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JAVA序列化和反序列化的底层实现原理解析 - Python技术站

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

相关文章

  • java复制文件的4种方式及拷贝文件到另一个目录下的实例代码

    Java复制文件的4种方式及拷贝文件到另一个目录下的实例代码 在Java中,复制文件可以使用多种方式,这里详细介绍4种常用的方法及对应的实例代码。 1. 使用 InputStream 和 OutputStream 进行复制 第一种方式是使用 InputStream 和 OutputStream,具体步骤如下: 创建 File 对象表示输入文件和输出文件; 创…

    Java 2023年5月20日
    00
  • java swing实现简单计算器界面

    创建Java Swing的简单计算器界面的步骤如下: 1. 创建一个Java项目 首先,在IDE(例如Eclipse、IntelliJ IDEA等)中创建一个Java项目。可以选择用Maven或Gradle进行管理,这里我们选择Gradle。 2. 导入Swing库 在项目中引入javax.swing和java.awt库,这些库中包含了Swing所需要的组件…

    Java 2023年5月18日
    00
  • 使用JDBC从数据库中查询数据的方法

    使用JDBC从数据库中查询数据的方法需要经过以下几个步骤: 1. 引入JDBC依赖 使用JDBC需要先引入相应的jar包,常见的JDBC库有MySQL Connector、Oracle JDBC等。以Maven项目为例,可以在pom.xml文件中添加以下Maven依赖: <dependency> <groupId>mysql</…

    Java 2023年5月20日
    00
  • URL @PathVariable 变量的匹配原理分析

    URL @PathVariable 变量的匹配原理分析 1. URL 匹配原理 在 Spring MVC 中,请求 URL 会被匹配到某个处理器方法,其中有以下几个步骤: 首先会去掉请求 URL 中的上下文路径(context path),然后从剩下的 URL 端点(endpoint)开始匹配; 然后按照 URL 模板(url template)进行匹配,其…

    Java 2023年6月15日
    00
  • PHP MVC模式在网站架构中的实现分析

    PHP MVC模式在网站架构中的实现分析 什么是MVC模式 MVC即Model-View-Controller,模型-视图-控制器,是一种常用的软件设计模式,通过将应用程序分成不同的三个部分,来实现分离关注点(Separation of Concerns),来提高代码的可维护性和可重用性。 模型(Model):负责处理数据的读取和存储,以及对其进行逻辑处理。…

    Java 2023年5月20日
    00
  • SpringData JPA中@OneToMany和@ManyToOne的用法详解

    下面我将详细讲解“SpringData JPA中@OneToMany和@ManyToOne的用法详解”的完整攻略。 什么是@OneToMany和@ManyToOne 在关系型数据库中,一个对象与另一个对象之间存在着不同的关系,如一对一、一对多、多对一、多对多等。而在Java中,对象之间的关系可以用多种方式来表示和映射到数据库中。Spring Data JPA…

    Java 2023年5月20日
    00
  • 使用Spring组合自定义的注释 mscharhag操作

    下面是关于“使用Spring组合自定义的注释 mscharhag操作”的完整攻略,包含两个示例说明。 使用Spring组合自定义的注释 mscharhag操作 Spring是一个非常流行的Java应用程序框架,它提供了一全面的编程和配置模型,用于构建现代化的基于Java的企业应用程序。在Spring中,注解是一种常重要的机制,它可以帮助我们更加方便地配置和管…

    Java 2023年5月17日
    00
  • Java构造函数通透理解篇

    Java构造函数通透理解篇 什么是构造函数 构造函数是一种特殊的函数,用于在创建对象时进行初始化操作。在Java语言中,构造函数名称必须与类名称完全一致,且没有返回值类型,因为构造函数的返回值类型就是类本身。 构造函数的作用 构造函数的主要作用是用于在创建对象时进行初始化操作,它会被自动调用,并设置类的初始状态。在构造函数中,可以进行对对象的属性进行初始化,…

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