实体类实现 Serializable 接口&&序列化和反序列化

357 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第12天,点击查看活动详情

之前在看组里其他前辈写的项目代码时,就有注意到前辈在定义每个实体类时都实现了 Serializable 接口。当时看到后有些好奇,因为自己之前在练习时,没有注意一定实现这个接口,看到前辈们的代码,每个实体类都有实现这个接口,感觉不会是没有目的的随便写的,然后就去了解了一下 Serializable 接口,记录一下。

Serializable 接口

image.png

在代码中点进 Serializable 接口,就会来到上图,从图中我们可以看到它是一个空接口。Serializable 是 java.io 包中定义的,用于实现 Java 类序列化操作而提供的一个语义级别的接口。一个类只有实现了 Serializable 接口,它的对象才能被 序列化

序列化

通过一个例子,理解序列化:甲、乙两人相隔两地,想要进行聊天,传播信息就需要媒介,序列化 就相当于电话,甲想要跟乙交流,就要通过电话传递信息。

序列化和反序列化

序列化:将对象状态信息转化成可以存储或传输的形式的过程。(Java 中就是将对象转化成字节序列 byte[] 的过程)

反序列化:从存储文件中恢复对象的过程(Java 中通过字节序列化转化成对象的过程)

为什么要序列化/反序列化?

Java 中对象都是存储在内存中,准确的说是 JVM 的堆或栈内存中。可以在各个线程之间进行对象传输,但是 无法进程 之间进行传输。 如果需要在 网络传输中传输对象 也是 没有办法 的,而且内存中的对象也 没有办法 直接 保存成文件

对对象进行 序列化,序列化对象后,Java 对象就变成了 字节序列,而字节序列是 可以传输和存储的反序列化 就可以通过序列化产生的字节序列再恢复成 序列化之前的 对象状态及信息。

注意

序言中说的不对,我看的项目代码中,前辈雀食很多实体类都实现了 Serializable 接口,但是,其实实体类 不一定 要实现Serializable 接口,只有 JDK 自带的 序列化才需要这么做,使用 json 序列化就不需要了。

Serializable 接口实现原理

接上面 Serializable 接口话题继续,很明显它是个空接口,没有任何方法和字段,只是用于表示可序列化的语义。

实现了 Serializable 接口的类可以被 ObjectOutputStream 转换成 字节流,同时也可以通过 ObjectInputStream 再将其解析为 对象。例如:可以将 序列化对象 写入 文件 后,再次从 文件 中读取它并 反序列化对象,即,可以使用 表示对象及其数据的类型信息和字节内存 中重新创建 对象

其实无论什么编程语言,其底层涉及 IO操作 的部分还是由 操作系统 帮其完成的,而底层 IO操作 都是以 字节流 的方式 进行的,写操作 涉及将 编程语言数据类型 转换成 字节流读操作 涉及将 字节流 转换成 编程语言特定的数据类型。而 Java 作为一个 面向对象 的编程语言,对象 作为其主要的数据类型载体,为了完成对象数据的 读写操作,就需要一种方式让 JVM 知道在进行 IO操作 时如何将 对象数据 转换成 字节流,以及如何将 字节流数据 转换成 特定的对象,Serializable 接口就承担了这一角色。Serializable 接口就相当于一个表示接口,它其实是给 JVM 看的,告诉 JVM,我不对这个类做序列化了,你(JVM) 帮我序列化就好了。

常用场景

  • 需要把内存中的对象状态数据保存到一个文件或者数据库中时;如:利用 mybatis 框架编写持久层 insert 对象数据到数据库中时;
  • 网络通信时需要用套接字在网络中传送对象时;如:使用 RPC 协议进行网络通信时;

关于 Serializable 接口以及序列化、反序列化就记录这么多,收获很大。希望本文章能够帮助你理解这个接口的用处及原理。
有错误,望指正!
我向你敬礼啊,Salute!