本篇博客的目的:在 【Redis入门十五:Java中使用Redis五:利用Jedis缓存数据一;(其实,就是利用redis存储对象)】中,遇到了对象序列化的内容,这儿特地的说明一下;
关于对象序列化的内容,可以参考
● Java序列化:【Java输入输出流九:对象序列化(需要用到字节流中的ObjectOutputStream[对象输出流]和ObjectInputStream[对象输入流])】
● JSON序列化:【JSON六:Java:对象集合序列化成JSON(数组);JSON(数组)反序列化为对象集合;】
序列化可以这样理解:(起码目前是这样)
● 有【发送方】和【接收方】,两方之间发送的是对象;
● 序列化可以看成是一种【两方之间约定好的,对象的“编码方式”】;被序列化后的对象,两方都可以【按照序列化的规则】将对象还原;
● 具体的“编码方式”,有【Java中的需要实现Serializable接口的那个序列化】,【JSON序列化】等;
● 在【Redis入门十五:Java中使用Redis五:利用Jedis缓存数据一;(其实,就是利用redis存储对象)】中,介绍的Redis通过JSON序列化的过程中;【发送方】和【接收方】都是Java程序,redis数据库只是起了一个”暂存数据“的作用;如下图所示;
《深入理解计算机系统》这本经典教材,以后如有必要最好是瞅一瞅;因为很多在应用层使用的技术,了解其底层原理还是比较重要的。
以下内容完全转载自【Java序列化闲聊:序列化和Json】 ;该文的作者是【Ciruy B.Heimerdinger】
(PS:该博主还有很多其它的优秀文章,可以参考!)
前言
其实我挺纠结的,在纠结到底要不要写这个模块的博客,因为序列化这个模块说简单,按照一些人的说法,其实也就是调两个函数的事情,说困难,铺开就让人感觉范围很广。
序列化
什么是序列化,我们在编程的时候,看到的花花绿绿的对象们,肯定在计算机里面通过一种方式存储;在网络上进行传输的时候,也肯定需要规定一种方式来让传输的双方能互相理解,不然我传输过去的数据即使你获取到了,也毫无意义。这种方式就是序列化,然后将序列化后的数据再通过规则转换回我们所需要的内容的方式就是反序列化。
《深入理解计算机系统》前几章就有这么一段话,翻译过来就是数据本身其实并没有意义,只有赋予其存在的意义也就是上下文,数据本身才有了意义。
本文就主要讲讲Android相关的序列化操作,Java中就有专门用于标记可序列化对象的接口Serializable,只有类被此接口标记了,Java才能对其执行序列化从而存储或者进行网络传输。
其实有很多的序列化方法,像Java本身的序列化方式(序列化后的结果可读性不是那么好),然后还有json,xml,还有protobuf等等。从事android开发的我还是比较熟悉json,所以本文还是打算围绕json来进行一些简单的讨论。
还是基于我之前所说的方法论,我们在探究问题的时候,必须要拨开问题表层的迷雾,抓住重点。那么Java中序列化的重点是什么?我想有以下两点:
* 如何保存当前对象的状态?
* 如何确保反序列化后对象的状态和序列化前的状态一样?
如何保存当前对象的状态
在Java中,所有对象不停追溯其父类,到最后都一定会追溯到Object类。父类也往往会永远一些成员变量,这些成员变量子类也能获取的到,所以,我们在保存当前对象的状态时,必须要同时保存父类,父类的父类等等等的状态。然后对于类的成员变量,我们肯定也需要去保存他的状态,如果成员变量并不是元数据,那么不好意思,我们也需要去遍历其祖宗十八代从而确保我们完全保存了当前对象的状态。
适当归纳一下,序列化算法一般会按照以下步骤做如下事情:
1. 将对象实例相关的类元数据输出
2. 遍历对象实例中的非元数据成员变量,遇到元数据按照步骤一的方式直接输出,按照此逻辑递归遍历直至遍历完成全部变量引用。
如何确保反序列化后对象的状态和序列化前的状态一样
的确,常规状态下,反序列化的实例和序列化前的实例其实是两个实例了。就好比一对双胞胎长得一模一样,做事方式,行为完全一样,但是你能说他们是同一个人吗?不能吧,更何况如果是通过网络传输后,在不同计算机上的序列化前后的实例,更不可能是同一个对象了。
但是实际上,对于这种情况,其实大多数情况下,我们睁一只眼闭一只眼,既然行为都完全一样,很多时候也就不用在意了。但是如果我们偏偏有强迫症呢?那么java也提供了Object readResolve(Object)方法,通过这个方法,我们能对反序列化的结果进行修正,传入的参数是之前所说的双胞胎实例,返回的是最后反序列化的结果。特别是在单例模式中,如果你拥有序列化前的实例,直接返回序列化前的实例,这能确保单例对象的唯一性。
Json解析
接下来讲讲Json的解析吧,Json的基础我就不专门讲了,但是对于Json解析的原理,我还是想说两句的。Json也是一种序列化的方式,所以Json解析也就是一种反序列化的方式。
据我所知,当下对于Json的解析分为两种,对于数据量较小的Json数据和对于数据量很大的Json数据。
数据量较小的Json数据
如果是数据量较小的Json数据,我们只需要将Json串一口气读取到内存里,直接进行解析就行了,小Json串用哪种解析方式都差不多。将Json转换成对象,然后想拿哪个数据,直接拿就行了。
数据量较大的Json数据
对于数据量较大的Json数据,就比较值得玩味了,就需要什么事件驱动型的解析方式。我其实很反感这些故弄玄虚的人,明明很简单的事情非要弄得很复杂,可能他们认为这样显得自己的水平很高。如果是数据量较大的Json数据,我们该怎么办呢?
我想问问读者?如果打游戏对线时,你的技能没法秒掉对手怎么办?很简单,把对手的血线消耗到斩杀线不就行了吗?
那么怎么解析数据量大的Json数据?一样的道理,拆分Json直到每个片段能直接进行解析就行了。我们可以看到”,{,[,就表示着一个拥有的关系。为什么这么说呢?因为我们可以看出这三个标记前一定跟的是"key":(最外层的{除外),这个的意思就是,当前的实例中有一个名字为key的成员变量,然后成员变量的结构就囊括在””,{},[]里,可能是元数据,对象,或者数组。这样一来处理就方便很多了,最直观的方法就是直接按照当前key相对于最外层的{}的拥有关系直接将Json文件拆分成多个小文件,直接按照从外到内的拥有关系搭建文件夹结构,然后文件夹中的文件就一定是能直接进行解析的Json数据。通过这样的方法,我们希望在Json数据中获取到什么数据,都能获取到了。
特别是当我们已经知道Json的数据结构时,我们都不用像之前所说的一层一层解析,从而构建一套基于拥有关系的文件夹系统,我们直接遍历一遍Json数据流,动态统计[和{的数量,如果遇到],}就将相应对应的计数减一,当发现和我们知道的数据结构中的两个token数量一致并且”key”值相同。那么恭喜你,你找到了你想要的数据。
本文探讨了Java中利用Jedis进行对象缓存时的序列化技术,重点关注Java序列化与JSON序列化在对象存储过程中的作用。通过《深入理解计算机系统》的视角,解析了序列化和反序列化的原理,以及如何确保数据一致性。

411

被折叠的 条评论
为什么被折叠?



