导读:最近在作项目的过程当中,发现一个问题,就是咱们最开始的时候,传递参数包括返回类型,都有map类型。可是因为map每次都要匹配key值,很麻烦。因此在以后就将参数传递和返回类型全都改为了实体bean,而且让每一个bean都实现了Serializable接口。而后,在这里的时候,就有点疑惑。首先:为何要进行序列化;其次:每一个实体bean都必须实现serializabel接口吗?最后:我作一些项目的时候,没有实现序列化,一样没什么影响,而后如今作项目须要序列化,到底何时应该进行序列化操做呢?css
本篇文章,是我对于序列化这个话题的一点小小的思考,可能还不太成熟,请每个路过的人不吝赐教,在此,先谢过了!html
In computer science, in the context of data storage, serialization is the process of translating data structures or object state into a format that can be stored (for example, in a file or memory buffer, or transmitted across a network connection link) and reconstructed later in the same or another computer environment.[1] When the resulting series of bits is reread according to the serialization format, it can be used to create a semantically identical clone of the original object.
java
那我也有看过不少的博客包括书,可是我以前其实一直不太理解这个序列化,虽然一直都在用。今天在看资料 的时候,发现致使这种现象的缘由,多是我以前看的一些介绍里面,忽略了一个很关键的因素:object state info对象的状态信息 。也就是说,其实序列化,它是完整的保存了某一状态下的对象信息,是一个总体,而不是零散的!我在一个IBM工程师的博客里面看到一个说法,我感受对于我理解序列化颇有帮助,他说序列化的过程,就是一个“freeze”的过程,它将一个对象freeze住,而后进行存储,等到再次须要的时候,再将这个对象de-freeze就能够当即使用。git
1,存储对象在存储介质中,以便在下次使用的时候,能够很快捷的重建一个副本。也就是When the resulting series of bits is reread according to the serialization format, it can be used to create a semantically identical clone of the original object.程序员
问题:我没有实现序列化的时候,我同样能够存入到个人sqlserver或者MySQL、Oracle数据库中啊,为何必定要序列化才能存储呢????github
2,便于数据传输,尤为是在远程调用的时候!redis
结合到第二点的问题,就是说在我存储的时候,不经过序列化也同样完美存储,为何要画蛇添足?额,通过我阅读文档和书籍,以及作项目的经验总结(反正就是以前混迹在编码中的一系列经验总结),在存储时须要序列化,这是确定的。你们知道的是序列化是将对象进行流化存储,咱们有时候感受本身在项目中并无进行序列化操做,也同样是存进去了,那么对象须要通过序列化才能存储的说法,彷佛从这儿就给阉割了。事实到底是怎样的呢?sql
首先看咱们经常使用的数据类型类声明:数据库
public final class String implements java.io.Serializable, Comparable<String>, CharSequence
public class Date implements java.io.Serializable, Cloneable, Comparable
而像其余int、long、boolean类型等,都是基本数据类型,数据库里面有与之对应的数据结构。从上面的类声明来看,咱们觉得的没有进行序列化,实际上是在声明的各个不一样变量的时候,由具体的数据类型帮助咱们实现了序列化操做。
拿到这儿的时候,就又有一个问题,既然实体类的变量都已经帮助咱们实现了序列化,为何咱们仍然要显示的让类实现serializable接口呢?数据结构
请注意我以上的说法:首先,序列化的目的有两个,第一个是便于存储,第二个是便于传输。咱们通常的实体类不须要程序员再次实现序列化的时候,请想两个问题:第一:存储媒体里面,是不是有其相对应的数据结构?第二:这个实体类,是否须要远程传输(或者两个不一样系统甚至是分布式模块之间的调用)?
若是有注意观察的话,发现序列化操做用于存储时,通常是对于NoSql数据库,而在使用Nosql数据库进行存储时,用“freeze”这个说法来理解是再恰当不过了,请在NoSql数据库中,给我找出个varchar,int之类的数据结构出来? 若是没有,但咱们又确实须要进行存储,那么,此时程序员再不将对象进行序列化,更待什么时候?
备注:若是有人打开过Serializable接口的源码,就会发现,这个接口实际上是个空接口,那么这个序列化操做,究竟是由谁去实现了呢?其实,看一下接口的注释说明就知道,当咱们让实体类实现Serializable接口时,实际上是在告诉JVM此类可被序列化,可被默认的序列化机制序列化。
而后,须要说明的是,当咱们在实体类声明实现Serializable接口时,再次进行观察,会发现这些类是须要被远程调用的。也就是说须要或者可能须要被远程调用,这就是序列化便于传输的用途。
慎重声明:以上全部言论,都是本宝宝通过项目中的具体观察,以及阅读一些文章以后的所谓经验之谈,且看且见谅吧!
上回说到了关于序列化的一些基本状况,那么,接下来的一个问题是:若是咱们要实现序列化操做,是否必定要经过实现Serializable接口的方式?PS:其实,我只是不明白,为何你们一提到序列化就说特别简单,实现Serializable接口就OK了?我就一直在想,这是不是目前咱们所能拥有的最佳选择?
请你们先看一篇文章分析:https://github.com/eishay/jvm-serializers/wiki
文章说得很清楚,图文并茂的,那么多选择,本身看着办吧。不过我最近作的一个项目使用的是protostuff!
诚如你们在第三节分享的连接文章所见,经过实现Serializable接口的方式去进行序列化操做,在性能上来说并非最佳选择。那么,在性能考虑的状况下,不少人都会选择其余更为高效率的产品替代serializable接口,如今问题来了:
1,若是我经过Serializable接口实现,那么我只须要在类声明时实现它便可
2,若是我经过其余方式实现,那么我将不得不本身重写工具类,不能再经过实现serializable接口的方式去进行序列化了。在使用上,大大的不怎么方便!
PS:项目中总会用到个什么redis,mongoDB啥的,其实每次存取都有那么一个数据封装处理的过程,额,也差不了这一点了。那么有没有现成的人家封装好的呢?本身找吧,确定是有的。其实,我就是不明白,若是是用了第三方的工具去实现序列化,那么在序列化进行远程调用的时候,到底应该在哪儿进行显示的序列化或者反序列操做?我刚开始想在Dao层,但这样子的话,本身模块操做不也得来那么一波序列化反序列化操做嘛。由于我目前确实只是在从NoSql数据库中存取数据时用到了第三方的序列化工具,而在远程调用的时候,没有啊!之前都是直接实现Serializable接口的,唉。。。。学艺不精啊!
跪求指点!!!!!
其实,很长的一段时间里,我一直觉得java底层包自带的方法必定会是最好的,包括各个框架,我都更愿意去用它自己就有的工具。可是,可能那些自带的方法,尤为是向Serializable接口,从jdk1.1开始就有了,通过了长时间的考验,性能上可能不是最好的,但它的稳定性绝对是值得确定的。那么,其实在使用的时候,仍是根据自身的状况考虑吧。在技术乃至于架构或者说各类系统设计,最实用最适合的,才是最好了!
其实我还有一个问题,不见得本身模块会和数据库部署到同一个机器上啊,因此仍是得考虑都传输时的序列化问题,那若是使用第三方的工具,不都得来那么一波嘛,这代码量就又活生生的多了那么点儿。唉,不说了,我这是越说越晕,回家吃饭!