共计 2718 个字符,预计需要花费 7 分钟才能阅读完成。
为什么要序列化?
如果光看定义我想你很难一下子了解序列化的意义,那么咱们能够从另一个角度来感受一下什么是序列化。
都玩过游戏么?玩过的同学应该晓得游戏里有一个叫『存档』的性能,每次不想玩的时候能够把以后进度存档,下次有工夫想玩的时候,间接载入存档就能够接着玩了,这样的益处是之前的游戏进度不会失落,要是每次关上都从新玩预计大家也没什么急躁了。
如果把面向对象的思维带到游戏的世界,那在咱们眼中不论是游戏角色还是游戏中的怪兽、配备等等都能够看成是一个个对象:
角色对象(蕴含性别、等级、经验值、血量、挫伤值、护甲值等属性)
怪兽对象(蕴含类型、血量、等级等等属性)
配备对象(蕴含类型、挫伤值、附加值等等属性)
在玩游戏的过程中创立一个游戏角色就如同是创立了一个角色对象,拿到一套配备就如同创立了一个配备对象,路上遇到的怪兽等等也都是对象了。
咱们再用计算机的思维去思考,创立的这些对象都是保留在内存中的,大家都晓得内存的数据是短暂保留的,断电之后是会隐没的,然而游戏通过手动存档之后就算你关机几天了,再次进入游戏读取存档,你会发现之前在游戏中创立的角色和配备都还在呢,这就很奇怪了,明明内存的数据断电就隐没了,这是为什么?
稍加思考就晓得,咱们在存档的过程中就是将内存中的数据存储到电脑的硬盘中,硬盘的数据在关机断电后是不会失落的(别杠,硬盘损坏数据失落先不思考)。这个过程就是对象的长久化,也就是咱们明天要讲的对象序列化。对象的序列化逆过程就叫做反序列化,反序列化也很好了解就是将硬盘中的信息读取进去造成对象。
什么是序列化?
后面引入游戏的例子是为了让大家活泼地了解什么是序列化和反序列化。简略总结一下就是:
序列化是指将对象实例的状态存到存储媒体的过程
反序列化是指将存储在存储媒体中的对象状态装换成对象的过程
用更为形象的概念来讲:
序列化:把对象转化为可传输的字节序列过程
反序列化:把字节序列还原为对象的过程
序列化的机制
序列化最终的目标是为了对象能够跨平台存储和进行网络传输,而咱们进行跨平台存储和网络传输的形式就是 IO,而 IO 反对的数据格式就是字节数组。
那当初的问题就是如何把对象转换成字节数组?这个很好办,个别的编程语言都有这个能力,能够很容易将对象转成字节数组。
认真一想,咱们单方面的把对象转成字节数组还不行,因为没有规定的字节数组咱们是没方法把对象的本来面目还原回来的,简略说就是将对象转成字节数组容易然而将字节数组还原成对象就难了,所以咱们必须在把对象转成字节数组的时候就制订一种规定(序列化),那么咱们从 IO 流外面读出数据的时候再以这种规定把对象还原回来(反序列化)。
还是拿下面游戏那个例子,咱们将正在玩的游戏存档到硬盘,序列化就是将一个个角色对象和配备对象存储到硬盘,而后留下一张原来对象的构造图纸,反序列化就是将硬盘里一个个对象读出来照着图纸一一还原复原_java 培训。
常见序列化的形式
序列化只是定义了拆解对象的具体规定,那这种规定必定也是多种多样的,比方当初常见的序列化形式有:JDK 原生、JSON、ProtoBuf、Hessian、Kryo 等。
(1)JDK 原生
作为一个成熟的编程语言,JDK 自带了序列化办法。只须要类实现了 Serializable 接口,就能够通过 ObjectOutputStream 类将对象变成 byte[]字节数组。
JDK 序列化会把对象类的形容信息和所有的属性以及继承的元数据都序列化为字节流,所以会导致生成的字节流绝对比拟大。
另外,这种序列化形式是 JDK 自带的,因而不反对跨语言。
简略总结一下:JDK 原生的序列化形式生成的字节流比拟大,也不反对跨语言,因而在理论我的项目和框架中用的都比拟少。
(2)ProtoBuf
谷歌推出的,是一种语言无关、平台无关、可扩大的序列化构造数据的办法,它可用于通信协议、数据存储等。序列化后体积小,个别用于对传输性能有较高要求的零碎。
(4)Hessian
Hessian 是一个轻量级的二进制 web service 协定,次要用于传输二进制数据。
在传输数据前 Hessian 反对将对象序列化成二进制流,绝对于 JDK 原生序列化,Hessian 序列化之后体积更小,性能更优。
(5)Kryo
Kryo 是一个 Java 序列化框架,号称 Java 最快的序列化框架。Kryo 在序列化速度上很有劣势,底层依赖于字节码生成机制。
因为只能限定在 JVM 语言上,所以 Kryo 不反对跨语言应用。
(6)JSON
下面讲的几种序列化形式都是间接将对象变成二进制,也就是 byte[]字节数组,这些形式都能够叫二进制形式。
JSON 序列化形式生成的是一串有规定的字符串,在可读性上要优于下面几种形式,然而在体积上就没什么劣势了。
另外 JSON 是有规定的字符串,不跟任何编程语言绑定,人造上就具备了跨平台。
总结一下:JSON 可读性强,反对跨平台,体积略微逊色。
JSON 序列化常见的框架有:
fastJSON、Jackson、Gson 等。
序列化技术的选型
下面列举的这些序列化技术各有优缺点,不能简略地说哪一种就是最好的,不然也不会有这么多序列化技术共存了。
既然有这么多序列化技术可供选择,那在理论我的项目中如何选型呢?
我认为须要联合具体的我的项目来看,比拟技术是服务于业务的。你能够从上面这几个因素来思考:
(1)协定是否反对跨平台
如果一个大的零碎有好多种语言进行混合开发,那么就必定不适宜用有语言局限性的序列化协定,比方 JDK 原生、Kryo 这些只能用在 Java 语言范畴下,你用 JDK 原生形式进行序列化,用其余语言是无奈反序列化的。
(2)序列化的速度
如果序列化的频率十分高,那么抉择序列化速度快的协定会为你的零碎性能晋升不少。
(3)序列化生成的体积
如果频繁的在网络中传输的数据那就须要数据越小越好,小的数据传输快,也不占带宽,也能整体晋升零碎的性能,因而序列化生成的体积就很要害了。
小结
(1)为什么咱们要序列化?
因为咱们须要将内存中的对象存储到媒介中,或者咱们须要将一个对象通过网络传输到另外一个零碎中。
(2)什么是序列化?
序列化就是把对象转化为可传输的字节序列过程;反序列化就是把字节序列还原为对象的过程。
(3)序列化的机制
序列化最终的目标是为了对象能够跨平台存储和进行网络传输,而咱们进行跨平台存储和网络传输的形式就是 IO,而 IO 反对的数据格式就是字节数组。
将对象转成字节数组的时候须要制订一种规定,这种规定就是序列化机制。
(4)常见序列化的形式
当初常见的序列化形式有:JDK 原生、JSON、ProtoBuf、Hessian、Kryo 等。
(5)序列化技术的选型
选型最重要的就是要思考这三个方面:协定是否反对跨平台、序列化的速度、序列化生成的体积。