关于Gson序列化与反序列化的一些总结

来源:互联网 发布:热能感应软件 编辑:程序博客网 时间:2024/06/06 00:02

一直以来是做Windows C++方面的开发,但在公司目前做的是一个Web与Windows C++相结合的项目。在做Windows方面的功能时,有时需要与Web后台服务进行交互,发出相关请求以获取数据。所以当本地Windows程序出现Bug时,有部分原因是请求后台数据时导致的错误。由于是两者结合的项目,所以耦合度较大,后台有专门负责Windows客户端请求的响应。

最近Windows客户端出现请求错误,既然是与自己本职工作方面相关的问题,所以此类的后台处理便亲自来跟踪调试。通过跟踪,发现后台在处理与客户端的会话时,通过Gson这种方式把会话信息对象进行序列化保存,并在需要的时候反序列化成会话对象。虽说在校期间也学过Java,但是后来自己主攻Windows C++,所以虽然大概知道序列化的概念,但对具体内容和实现不甚了解。刚开始看到Gson这个东西时,首先想到了Json,但不十分明朗,于是到网上去查,然后才知道这是 Google提供的用来在Java对象和Json数据之间进行映射的Java类库,也就是对Json的一个封装库,是对象与Json之间的转换操作更为简便(PS:Json的知识在这里我不再讲述,可自行百度)。

为了弄懂代码意思,我在网上查了Gson的使用方法,从有限的中文资料中,发现大部分的作者在给出代码实例时,都是以Bean的形式定义对象的,每个属性都用相关的Set和Get方法,在直观的代码的影响下,我想当然的认为Gson在序列化和反序列化的时候是会调用这些方法。可是,我错了,通过验证,发现不是这样的。首先我打断点,发现根本不会触发改方法。或许是因为某种机制(Java不太熟,具体什么尚说不出来,像C++某些地方打断点就无法触发,比如有一些超时操作,打了断点该超时可能就过去了)触发不到这里,于是我修改为在代码中进行输出,结果证明,在用Gson.fromJson()反序列化生成对象时确实不会调用Set方法,也就是说,对象的属性状态不是通过这些方法来设置的(开始我还以为跟Hibernate的Bean对象类似呢)。接着我又把所有的Set和Get方法删除,发现依旧能够正常序列化和反序列化,所以就更加印证了这个事实。因具体实现不太清楚,所以无法解释这个过程是怎么实现的,但大概猜想如下:在用Gson.toJson()进行序列化时,Gson按照成员属性的声明顺序依次进行转换,最后得到Json字符串;在进行反序列化时,先创建一个对象,然后通过解析Json字串,依次填写对应属性值(此处只是一个大概过程猜想,这里有一篇介绍Gson反序列化创建对象的文章,不知可靠性高不高,大家可以参考一下 http://www.tuicool.com/articles/6FrYniN)。

最后我要说一点自己的发现:Gson反序列化时有自己的默认的数据格式,对于数字类型的数据,会默认转换为Double型,对于对象类型会转换为数组型,对于枚举类型会转换为String型,等等。举个例子:

    public class MyType{        String name;        int age;        public MyType(String iName, int iAge){            name = iName;            age = iAge;        }    }    public enum PackageState {        PLAY, UPDATE, UPDATING, DOWNLOAD, DOWNLOADING,    }    public class MyCombineType{        Object myType;        int code;        Object state;        Object myNum;        public MyCombineType(MyType iMyType, int iCode, PackageState iState,,int myNum){            this.myType = iMyType;            code = iCode;            state = iState;            this.myNum = myNum;        }    }        Gson myGson = new GsonBuilder().create();        MyType myType = new MyType("ZDL", 24);        MyCombineType myCombineType = new MyCombineType(myType, 1, PackageState.PLAY, 7);        String myStr = myGson.toJson(myCombineType);        MyCombineType myCombineType1 = myGson.fromJson(myStr, MyCombineType.class);
调试断点到最后一行,通过查看变量值可以看到:
myCombineType1对象的myType属性成了有两个对象的数组,分别是String型和Double型,如下图:
<img src="http://img.blog.csdn.net/20150602175129412?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvWl9kb25nbA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
<span style="font-family: Arial, Helvetica, sans-serif;">state属性成了String类型,如下图:</span>
<span style="font-family: Arial, Helvetica, sans-serif;"><img src="http://img.blog.csdn.net/20150602175153140?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvWl9kb25nbA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" /></span>
myNum属性成了Double类型,如下图:
<img src="http://img.blog.csdn.net/20150602175205261?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvWl9kb25nbA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />



 

0 0
原创粉丝点击