本文是Gson的基本使用和简单的面试题,需要阅读者了解Java及Json数据格式后阅读
文章目录
Gson的基本使用
引入
Gradle:
dependencies {
implementation 'com.google.code.gson:gson:2.8.5'
}
Maven:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
Gson实例的获取方式
1.new Gson()
Gson mGson = new Gson();
2.GsonBuilder.create();
GsonBuilder mGsonBuilder= new GsonBuilder();
Gson mGson = mGsonBuilder.create();GsonBuilder mGsonBuilder= new GsonBuilder();
Gson mGson = mGsonBuilder.create();
通过看源码不难发现其实第二种方法也是调用了Gson()的构造方法,只不过第一种构造采用了默认的参数,第二种动态配置了参数,可以让Gson实例支持更多的功能,可以通过改变GsonBuilder的参数来修改,之后我们主要使用第二种方法来构造Gson实例
Gson的简单使用
序列化
首先我们创建一个需要序列化的model Student。它包括学生的id,年龄和学生的老师具体看代码。
class Student{
String id;
int age;
Teacher mTeacher;
Student(String id,int age,Teacher teacher){
this.id = id;
this.age = age;
this.mTeacher = teacher;
}
}
class Teacher{
String id;
boolean sex;
Teacher(String id,boolean sex){
this.id = id;
this.sex = sex;
}
}
然后创建一个Gson实例进行序列化
Teacher teacher1 = new Teacher("t11256",true);
Student student1 = new Student("s21213",12,teacher1);
//方法1
Gson mGson = new Gson();
String jsonStr = mGson.toJson(student1);
//方法2
GsonBuilder mGsonBuilder = new GsonBuilder();
Gson mGson = mGsonBuilder.create();
String jsonStr = mGson.toJson(student1);
这样就可以把实体类转为Json数据格式,
{"age":12,"id":"s21213","mTeacher":{"id":"t11256","sex":true}}
面试题
1.如果给int这样的基础数据类型不赋值会不会转化该字段?如果转化会是默认值0吗?如果是引用
我们修改Student类的构造方法,然后不给age赋值看是否会转化。然后同样不给Student的teacher和id赋值,修改如下。
Student类
class Student{
String id;
int age;
Teacher mTeacher;
Student(){
}
Student(String id,int age,Teacher teacher){
this.id = id;
this.age = age;
this.mTeacher = teacher;
}
}
生成实例代代码
Student student1 = new Student();
其他的我们都不改变,看一下结果如何。
{"age":0}
答案:基础类型会转化且默认值为基础类型的默认值,而引用类型则不会转化。
既然引用类型没有赋值的情况下不能转化,那我们希望他转化有没有办法呢?当然是有的,之后我们会介绍。
反序列化
继续使用序列化中使用的类。我们把一个Json的字符串转化成实体类。代码如下:
需要反序列化的字符串
{"age":12,"id":"s21213","mTeacher":{"id":"t11256","sex":true}}
反序列化
String json = "{\"age\":12,\"id\":\"s21213\",\"mTeacher\":{\"id\":\"t11256\",\"sex\":true}}";
Gson gson = new Gson();
Student student = gson.fromJson(json,Student.class);
Log.d(TAG, "id:"+student.id+"\nage:"+student.age+"\nteacher:"+student.mTeacher.toString());
Teacher类修改如下:
class Teacher{
String id;
boolean sex;
Teacher(String id,boolean sex){
this.id = id;
this.sex = sex;
}
@NonNull
@Override
public String toString() {
return "tid:"+id+"\nsex:"+sex;
}
}
进行序列化之后的输出
id:s21213
age:12
teacher:tid:t11256
sex:true
我们可以看到json字符串已经成功转化成了实体类。
面试题
1.如果我转化的字符串多了字段或者少了字段会对反序列化有什么影响,反序列化还会正常进行吗?
我们修改需要反序列化的字符串如下
{"age1":12,"id1":"s21213","mTeacher":{"id":"t11256","sex":true}}
我们将age字段写成了age1,这样既少了age字段又多了一个age1字段,id同理也再来看看会有什么影响。运行结果如下
id:null
age:0
teacher:tid:t11256
sex:true
答案:多出的字段不会影响反序列化,缺少的字段如果是基础类型会赋默认值引用类型会是null
数组的(反)序列化
数据的序列化
我们已经学习了最基础的类的转化,现在来看看数据的转化,在Java中数组有Array和List的差别,我们知道在json中数组都是用[]括起来的,这个对于序列化有影响吗?
修改Student类如下
class Student{
String id;
int age;
String[] classmates = {"fenxi","xiaobai","xiaohei"};
List<Teacher> mTeacher = new ArrayList<>();
Student(){
}
Student(String id,int age,List teacher){
this.id = id;
this.age = age;
this.mTeacher = teacher;
}
}
修改初始化如下
Teacher teacher1 = new Teacher("t11256",true);
Teacher teacher2 = new Teacher("t22222",true);
Teacher teacher3 = new Teacher("t33333",true);
List<Teacher> list = new ArrayList<>();
list.add(teacher1);
list.add(teacher2);
list.add(teacher3);
Student student1 = new Student("s11111",12,list);
转化代码如下
Gson mGson = new Gson();
String jsonStr = mGson.toJson(student1);
Log.d(TAG, ""+jsonStr);
运行结果如下:
{"age":12,"classmates":["fenxi","xiaobai","xiaohei"],"id":"s11111","mTeacher":[{"id":"t11256","sex":true},{"id":"t22222","sex":true},{"id":"t33333","sex":true}]}
我们可以看到,不管是Array还是list,Gson转化的时候都是使用[]阔了起来,是没有区别对待的。
数组的反序列化
需要反序列化的Json
{'age':12,'classmates':['fenxi','xiaobai','xiaohei'],'id':'s11111','mTeacher':[{'id':'t11256','sex':true},{'id':'t22222','sex':true},{'id':'t33333','sex':true}]}
反序列化转化代码
String json = "{'age':12,'classmates':['fenxi','xiaobai','xiaohei'],'id':'s11111','mTeacher':[{'id':'t11256','sex':true},{'id':'t22222','sex':true},{'id':'t33333','sex':true}]}";
iGson gson = new Gson();
Student student = gson.fromJson(json,Student.class);
String classmate = "";
for (int i = 0;i<student.classmates.length;i++) {
classmate = classmate + "\n"+student.classmates[i];
}
Log.d(TAG, id:"+student.id+"\nage:"+student.age+"\nclassmates:"+classmate+"\nteacher:"+student.mTeacher.toString());
运行结果如下:
id:s11111
age:12
classmates:
fenxi
xiaobai
xiaohei
teacher:[
tid:t11256
sex:true,
tid:t22222
sex:true,
tid:t33333
sex:true]
可以看到反序列化已经成功了!
需要注意的是Set和上述的转化结果是一样的,因为Json并不区分底层实现,一概当做数组处理
面试题
1.Java中的数组有Array和List之分,它们在Gson序列化和反序列化中都可以使用吗?结果一样吗?
答案:都可以使用,结果一样。Gson对两种数据结构都进行了适配。
Maps的序列化
序列化
我们新建Map对象如下
Map<String,String> map = new HashMap<>();
map.put("1","this is one");
map.put("2","this,is two");
使用Gson对其进行序列化
Gson gson = new Gson();
String mapJson = gson.toJson(map);
Log.d(TAG, "mapJson:"+mapJson);
执行结果如下
mapJson:{"1":"this is one","2":"this,is two"}
和对象的序列化不同的是,map序列化的时候,key是map的key而不是变量的名称,当然了这一点也非常好理解。map本来就是键值对的格式存储。
反序列化
Map的反序列化,代码如下
String mapJson = "{\"1\":\"this is one\",\"2\":\"this is two\"}";
Gson gson = new Gson();
Map<String,String> map;
map = gson.fromJson(mapJson,Map.class);
Log.d(TAG, "map:\n"+map.toString());
运行结果
map:
{1=this is one, 2=this is two}
总结
至此,Gson的基础使用已经说完了,相信你也初步了解了Gson这个第三方库