java数据序列化与反序列化

来源:互联网 发布:ps淘宝店标图片制作 编辑:程序博客网 时间:2024/04/27 07:33

1.序列化与反序列化

序列化与反序列化就像数学里的函数和逆函数,比如把java对象转为json字符串操作当作函数f,那么把json字符串转为java对象的操作就可以视为f函数的逆函数。
用数学表达式来表示:f函数: n-----f----->f(n), f函数的逆函数:f(n)----f`---->n。
推广一下,java对象与字节数组的互转也是类似的,对应的可以学习thrift和protobuf的工作原理。
今天主要讲解下java对象和j son字符串的互转。

2.常见的java对象和j son字符串互转的类库。

用的比较多就是Gson,JackSon和fastjson,他们的功能性能比较不在本文的范畴,大家想了解的话可以自行Google。

但是它们的原理都说类似的,由于json的格式是有规则约束的,主要就是j son对象和json数组,最外层是个最大的j son对象,jsonobject可以包含jsonarray,jsonarray里又是json对象,对象的属性是k-v的格式。有点类似view和view group的关系。这么说还说有点抽象,那就看下面这个例子吧。

比如一个学生类Student:

public class Student{

public int id; //学号

public String name; //姓名

public int sex; //性别 0:男生 1:女生

}

new一个学生对象:

Student student = new Student();

student.id = 110;

student.name = "jack";

student.sex = 0;

这里的性别可以用枚举,当然不是很推荐,因为性能比较差,一般可以在Student类中声明两个static常量boy = 0, girl = 1;这样的话直接引用这两个常量来进行判断。这个类里面差成员属性我用的public修饰的,大家可能也会感觉奇怪,主要是private修饰的话性能比较差一些,并且要写很多的构造函数或者setter,getter函数,写起来比较麻烦,性能也不好。

回归主题,这个student对象对应的json如下:

    id : 110,

name : 'jack',

sex : 0

可以看出,java对象都可以通过拼接字符串的方法拼接出json字符串,同理json字符串都说解析出对应的java对象,不管多复杂的java对象抑或json字符串。

正式因为有章可循,所有才有gson之类的解析库,我们也不需要重复造轮子,在了解基本原理的基础上,灵活运用类库提供的序列化和反序列化的方法即可。当然首选我们先根据业务抽象出类结构,再和接口组沟通,定义传输结构。

3.gson的一些常见和特殊用法。

常见的有toJsion()和fromJson(),对应序列化和反序列化两种操作,由于纯手写代码,没有用ide,所以不要求精确无误,大家用ide看一下就知道了。这两种比较简单,就不写例子了,大家只要记住对应的步骤就行了,1.定义好接口传输数据结构,2.抽象出对应的model。

下面讲解两个项目里遇到的一些特殊用法。

1.用Gson来存储list

List<Menu> retList = gson.fromJson(jsonstr,  new TypeToken<List<Menu>>() {  }.getType()) 主要用到的是这个方法。(具体代码明天上)


2.用Gson@Expose标签来去掉不需要序列化或者反序列化的属性

@Expose标签有两个属性:

deserialize (boolean) 反序列化 默认 true

serialize  (boolean) 序列化 默认 true

使用 new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();创建Gson对象,没有@Expose注释的属性将不会被序列化

@Expose

private String username;

@Expose(serialize=false)

private int age ;


3.用Gson@SerializedName注解来修改k命名不一致问题

由于fromJson(String jsonStr, Class<T> class)方法需要json的k和对象的属性名一致,不然就会解析失败。但是由于后台人员的命名习惯或者历史遗留问题,常常出现几种命名方式,下划线和驼峰命名都有。但是为了保证android的命名一致,特别是对于那种有代码洁癖的程序员来说,肯定不能忍受这样的傻逼结构(吐槽一下)。

用法也很简单,在我们定义的model里使用Gson的,如下:

json对应的k-v中的k为divide_id,我们想改为divideId,我们就可以这样:

@SerializedName("divide_id")

public int divideId;

要使用new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();来构造gson对象


总结:这些小技巧是不是很简单,但是对代码可读性还是很重要的。















0 0
原创粉丝点击