【Java 学习之路】无序列化,必翻车:Java 对象持久化与类的序列化重要性

序列化(Serialization)和 反序列化(Deserialization)定义

序列化(Serialization):

序列化是指将对象的状态信息转换为可以存储或传输的格式的过程。在序列化过程中,对象的各种属性和数据被转换为字节流,以便将其保存到文件、数据库或通过网络传输。序列化通常涉及将对象的字段按照一定的协议转化为二进制数据,并保持对象的结构。

反序列化(Deserialization):

反序列化是序列化的逆过程,即将字节流还原为对象的过程。在反序列化中,字节流中的数据被解析,并重新构建为原始的对象。反序列化通常涉及将二进制数据按照序列化协议还原为对象的各个属性和数据。

说白了就是,序列化就是把你创建的类对象转换成可传输或保存的格式,例如字节流。这样,你可以通过网络将对象发送给其他服务器,或者将对象存储在文件中。反序列化则是将这些转换后的格式重新还原成原始的类对象,以确保其他服务器或者在之后的时间点能够正常使用这个类。

Java是如何实现 序列化(Serialization)和 反序列化(Deserialization)的

Java序列化(Serialization)

  1. 实现 Serializable 接口: 要使一个类可序列化,需要让该类实现 Serializable 接口。这个接口是一个标记接口,没有定义任何方法,只是用于标识该类可以进行序列化。

    java 复制代码
    public class MyClass implements Serializable {
        // 类的定义
    }
  2. 使用 ObjectOutputStream 创建一个 ObjectOutputStream 对象,将要序列化的对象写入输出流。

    java 复制代码
    try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("filename.ser"))) {
        MyClass obj = new MyClass();
        oos.writeObject(obj);
    } catch (IOException e) {
        e.printStackTrace();
    }

Java反序列化(Deserialization)

  1. 使用 ObjectInputStream 创建一个 ObjectInputStream 对象,从输入流中读取序列化的对象。

    java 复制代码
    try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("filename.ser"))) {
        MyClass obj = (MyClass) ois.readObject();
        // 使用反序列化得到的对象
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    }

到底什么才是 序列化(Serialization)和 反序列化(Deserialization)?

首先我们来了解一个概念 协议

协议(Protocol)是指在数据通信中,参与通信的各方之间达成的一种规定或约定,以便彼此之间能够正确、有效地进行信息交流和传递。协议定义了数据的格式、传输方式、通信顺序、错误处理等细节,确保通信的双方能够理解和遵循相同的规则。

我们常见的结构化数据传输协议

  1. JSON-RPC 和 XML-RPC: 这是两种基于 JSON 和 XML 的远程过程调用协议,用于在网络上传输结构化数据,并执行远程操作。
  2. SOAP(Simple Object Access Protocol): 一种基于 XML 的通信协议,通常用于 Web 服务之间的数据交换。
  3. HTTP(Hypertext Transfer Protocol): 虽然最初设计用于传输超文本,但由于其简单性和广泛的应用,HTTP 也被广泛用于传输结构化数据,特别是通过 RESTful 接口。
  4. REST(Representational State Transfer): 不是一个具体的传输协议,而是一种基于 HTTP 的架构风格,用于创建分布式系统。RESTful 服务通常使用 JSON 或 XML 格式传输结构化数据。
  5. GraphQL: 一种用于查询和修改结构化数据的查询语言和运行时环境,通常通过 HTTP 进行通信。
  6. Protocol Buffers(protobuf): 由 Google 设计的二进制序列化格式,用于定义结构化数据的协议。它可以用于多种语言,并且提供了高效的数据序列化和反序列化。

JAVA Class 文件的结构属性?

  1. 魔数(Magic Number): Class 文件的前4个字节是一个固定的魔数,用于标识该文件是否为有效的 Class 文件。魔数的值为 0xCAFEBABE
  2. 版本信息: 魔数之后的4个字节表示 Class 文件的次版本号和主版本号,用于指定 Java 运行时环境的版本。
  3. 常量池(Constant Pool): 常量池是一个表,用于存储编译时生成的各种字面量和符号引用。包括类名、方法名、字段名、字符串字面量等。
  4. 访问标志(Access Flags): 用于描述类或接口的访问权限和属性,例如 publicfinalabstract 等。
  5. 类索引、父类索引、接口索引集合: 用于确定类的层次结构,包括当前类的父类和实现的接口。
  6. 字段表(Field Table): 描述类或接口中声明的字段,包括字段的访问标志、名称、描述符等。
  7. 方法表(Method Table): 描述类或接口中声明的方法,包括方法的访问标志、名称、描述符等。
  8. 属性表(Attribute Table): 每个字段表和方法表中都可以包含多个属性,例如 Code 属性(包含方法体的字节码)、ConstantValue 属性(字段的常量值)等。
  9. 源文件属性(Source File Attribute): 用于指定源代码文件的名称。
  10. 行号表属性(Line Number Table Attribute): 用于调试,记录方法中源代码行号与字节码行号的对应关系。
  11. 局部变量表属性(Local Variable Table Attribute): 用于调试,记录方法中局部变量的信息。
  12. 异常表属性(Exception Table Attribute): 用于记录方法中可能抛出的异常。
  13. 内部类、外部类属性(Inner/Outer Class Attribute): 用于描述类的内部类和外部类的关系。

说白了,Java类也和 json text 一样属于一种结构,不过是一种复杂的数据结构,所以java calss在网络传输中有自己的传输协议。

Java的序列化协议

Java 使用一种特定的序列化协议来定义对象如何被转换为字节流以及如何在反序列化时还原为对象。这个协议被称为 Java 序列化协议。

java 复制代码
public class Le implements Serializable {
    private int l;
    public int lele() {
        return l + 1;
    }
}

Le 类的一个简化的序列化协议示例:

java 复制代码
AC ED 00 05   // 魔数
00 05         // 版本号
73 72 00 02   // Object 类描述符:类名为 "sr",serialVersionUID 为 2
6C 65 2E 4C 65 00 00 00 00 00 00 00 01 70 78 71 00 7E // 类名 "Le",字段个数为 1
00 02         // 类的字段个数(这里有一个字段)
5B 4C 65 00 00 00 00 00 00 00 01 6C 70 78 71 00 7E // 类型描述符 [Le;,字段名 "l",类型为 int
00 04         // 字段名长度
68 68 6F 77 00 00 00 00 00 01 // 字段值为 1

所以到底什么才是java的序列化和反序列化呢?

一句话说就是,Java类对象的序列化和反序列化是利用Java序列化协议,通过将Java对象(一种复杂的数据结构)转换为字节流的方式进行传输和存储的过程。

总结

一定要多思考,如果人永远待在舒适圈的话,人永远不会成长。共勉

觉得作者写的不错的,值得你们借鉴的话,就请点一个免费的赞吧!这个对我来说真的很重要。૮(˶ᵔ ᵕ ᵔ˶)ა

相关推荐
守护者1703 分钟前
JAVA学习-练习试用Java实现“使用Arrays.toString方法将数组转换为字符串并打印出来”
java·学习
源码哥_博纳软云4 分钟前
JAVA同城服务场馆门店预约系统支持H5小程序APP源码
java·开发语言·微信小程序·小程序·微信公众平台
禾高网络6 分钟前
租赁小程序成品|租赁系统搭建核心功能
java·人工智能·小程序
学会沉淀。12 分钟前
Docker学习
java·开发语言·学习
如若12313 分钟前
对文件内的文件名生成目录,方便查阅
java·前端·python
初晴~43 分钟前
【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)
java·数据库·redis·分布式·后端·spring·
yuanManGan1 小时前
数据结构漫游记:静态链表的实现(CPP)
数据结构·链表
黑胡子大叔的小屋1 小时前
基于springboot的海洋知识服务平台的设计与实现
java·spring boot·毕业设计
ThisIsClark2 小时前
【后端面试总结】深入解析进程和线程的区别
java·jvm·面试
雷神乐乐2 小时前
Spring学习(一)——Sping-XML
java·学习·spring