最近见到好多项目中写的代码,在实体类中实现了Serializable接口。说实话:这个在以前学习的时候,貌似学过,但是一直没有用过,所以看着一脸懵逼,但是别人总不可能随便写的吧.....所以就去查了一下这个接口。
一、 什么是Serializable接口
Serializable是java.io包中定义的,Serializable接口是一个空接口,即它不包含任何方法或字段。它的主要作用是标志一个类可以被序列化。序列化是指将对象转换为字节序列的过程,这样可以将对象的状态保存到磁盘中,或者通过网络传输对象。反序列化则是将字节序列恢复为对象的过程。只有一个类实现了Serializable接口,它的对象才能被序列化。
实现了Serializable接口的类可以被ObjectOutputStream转换为字节流,同时也可以通过ObjectInputStream再将其解析为对象。例如,我们可以将序列化对象写入文件后,再次从文件中读取它并反序列化成对象,也就是说,可以使用表示对象及其数据的类型信息和字节在内存中重新创建对象。
而这一点对于面向对象的编程语言来说是非常重要的,因为无论什么编程语言,其底层涉及IO操作的部分还是由操作系统其帮其完成的,而底层IO操作都是以字节流的方式进行的,所以写操作都涉及将编程语言数据类型转换为字节流,而读操作则又涉及将字节流转化为编程语言类型的特定数据类型。而Java作为一门面向对象的编程语言,对象作为其主要数据的类型载体,为了完成对象数据的读写操作,也就需要一种方式来让JVM知道在进行IO操作时如何将对象数据转换为字节流,以及如何将字节流数据转换为特定的对象,而Serializable接口就承担了这样一个角色。
二、什么是序列化
序列化是指把对象转换为字节序列的过程(将对象状态转换为可保持或传输的格式的过程),我们称之为对象的序列化,就是把内存中的这些对象变成一连串的字节(bytes)描述的过程。
而反序列化则相反,就是把持久化的字节文件数据恢复为对象的过程。
为什么要序列化?
- 把对象转换为字节序列的过程称为对象的序列化
- 把字节序列恢复为对象的过程称为对象的反序列化
什么情况下需要序列化?
常用场景:
- 需要把内存中的对象状态数据保存到一个文件或者数据库中的时候,这个场景是比较常见的,例如我们利用mybatis框架编写持久层insert对象数据到数据库中时;
- 网络通信时需要用套接字在网络中传送对象时,如我们使用RPC协议进行网络通信时;
当我们需要把对象的状态信息通过网络进行传输,或者需要将对象的状态信息持久化,以便将来使用时都需要把对象进行序列化
那为什么还要继承Serializable。那是存储对象在存储介质中,以便在下次使用的时候,可以很快捷的重建一个副本。
或许你会问,我在开发过程中,实体并没有实现序列化,但我同样可以将数据保存到mysql、Oracle数据库中,为什么非要序列化才能存储呢?
从上面的接口介绍中也可以看到Serializable接口只是一个空接口,可以将它理解成一个标识接口。
Serializable接口就是Java提供用来进行高效率的异地共享实例对象的机
制,实现这个接口即可。
三、为什么要定义serialversionUID变量
简单看一下 Serializable接口的说明
从说明中我们可以看到,如果我们没有自己声明一个serialVersionUID变量,接口会默认生成一个serialVersionUID。
但是强烈建议用户自定义一个serialVersionUID,因为默认的serialVersinUID对于class的细节非常敏感,反序列化时可能会导致InvalidClassException这个异常。
原文链接:
https://blog.csdn.net/qq_40036754/article/details/100886917
https://blog.csdn.net/qq_41879343/article/details/104813207