写在前面
一直在 Java 实体类中实现序列化接口,但是实体类对象为什么要实现序列化接口,什么是序列化呢?从来没有真正了解过,今天探寻一番!
什么是序列化
从字面上理解就是有序,标准而整齐。
想象我们中学时代的早操与大学入学时的军训的场景,我们排好队,迈着整齐的步伐进入操场做操、训练,结束后又迈着同样的步调返回教室或食堂。从进入操场到从操场出来,我们没有变,每个人还是在自己的位置上。这就是一个类似于序列化的场景,可能不太贴切...
标准的定义是这样描述的:序列化是一种处理对象流的机制,而所谓对象流就是将对象的具体内容流化。这么做的目的是方便进行读写操作和异域传输。
为什么JAVA对象需要实现序列化?
对象的序列化就是为了数据传输,在你的代码的里是对象格式,而在传输的时候不可能还保持这对象的样子。
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。
- 概念
- 序列化:把Java对象转换为字节序列的过程。
- 反序列化:把字节序列恢复为Java对象的过程。
- 用途 对象的序列化主要有两种用途:
- 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中。
- 在网络上传送对象的字节序列。
如何实现序列化?
implements Serializable 简单粗暴
在实现序列化接口后,java编译会提示生成一个序列化ID,可以默认生成,也可以自定义。这里的自定义并不是自己随便定义一个数字,而是根据当前类的一些特点如类名,成员变量等由系统来生成一个64位的哈希字段。
这个标记存在的意义就是告诉别人当前实体类已经实现了序列化,也可以被序列化。
- 序列化ID作用
- 序列化ID的每次生成不一定是相同的,当我们在修改实体类的变量或方法名等,会导致序列化ID出现变化。这个ID类似于version-版本号。
- 当我们将某个实体类对象持久化到本地设备后,可能过段时间,我们想要去修改类里面的某个变量或者说添加新的变量。如果说我们定义了序列化ID,那这时我们可以通过反序列化获取实体类的数据,然后再去添加或者修改某项数据。如果没有定义序列化ID,同样的我们去进行本地数据的反序列化,这时会因为序列化ID不一致而导致操作失败。
序列化的应用场景
-
一是实现pojo对象的读写操作
- 将每个对象转换为字节流,而这些字节流可以被持久化到设备上,再次读取时会将字节流还原成对象。相当于将大象切割成几份放到冰箱里,当拿出来时,还是一头活生生的大象。(这个比喻貌似比上文要生动贴切多了~)这里还原对象使用的是反序列化。当我们希望某些数据能在程序停止运行后,还能继续存在。在程序再次执行时还能获取这些数据时,或者让其他的程序也能够利用这些数据资源时。这就是我理解的应用场景一。
举一个例子:玩单机游戏时,玩了一半想存盘,那么存盘,就可以简单理解为将当前游戏运行的所有对象序列化保存到硬盘上,然后再次玩的时候,读取存档,就是反序列化,“再弄出这些对象出来”,继续运行。
-
二是实现网络间的数据传输
- 网络间的数据传输是高频发而且数据量也是非常大的。以订单数据传输为例,当我们希望获取到订单类里的全部数据并据此生成一份订单的excel文件时,这个订单类就必须要实现序列化,这是我理解的应用场景二。
最后
最近有点忙啊啊啊啊啊啊啊啊啊啊~~~~