本文是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這個第三方庫