Gson之常見的序列化與反序列化
序列化與反序列化
在Gson的語境中序列化就是說把Java 物件轉化為Json字串,反序列化就是說把Json字串轉化為Java物件。
新增依賴
本篇部落格基於Gson 2.8.0版
compile 'com.google.code.gson:gson:2.8.0'
簡單Java物件
比如有一個學生類如下:
public class Student {
public String name;
public int age;
public boolean isLOLPlayer;
}
序列化
Student stu=new Student("lin" ,18,true);
//通過預設的方式
Gson gson=new Gson();
String stuJson=gson.toJson(stu);
輸出的Json字串如下
{"name":"lin","age":18,"isLOLPlayer":true}
反序列化
//使用'是因為不想使用轉義字元\"
String stuJosn="{'name':'lin','age':18,'isLOLPlayer':true}";
Gson gson=new Gson();
Student stu = gson.fromJson(stuJosn, Student.class);
通過打斷點檢視生成的物件如下:
關於null值的處理
比如說name為null
Student stu=new Student(null,18,true);
這時候預設情況下Gson會忽略掉這個欄位,不產生相關的資訊
輸出結果
{"age":18,"isLOLPlayer":true}
那麼反過來情況也是一樣的,假設json字元創中沒有name欄位,產生的java物件name屬性為null。這時候就要小心了,很可能會產生空指標異常
陣列/List/Set
我們知道Json中有陣列是以[ ]括起來的部分,Gson可以將它反序列化為Java中的陣列、List、Set,我們可以根據自己的實際需求來選擇。
如下學生有很多書:
public class Student {
public String name;
public int age;
public boolean isLOLPlayer;
public ArrayList<Book> books;
}
序列化:
ArrayList<Book> books=new ArrayList<>();
books.add(new Book("Thinking in Java","6666",78.0f));
books.add(new Book("程式設計之美","8888",63f));
Student stu=new Student("shilang",18,true,books);
Gson gson=new Gson();
String stuJosn=gson.toJson(stu);
輸出的Json如下:
{
"age": 18,
"books": [
{
"bookName": "Thinking in Java",
"isbn": "6666",
"price": 78.0
},
{
"bookName": "程式設計之美",
"isbn": "8888",
"price": 63.0
}
],
"isLOLPlayer": true,
"name": "shilang"
}
你會發現其實程式碼和上面的簡單Java物件沒什麼區別,確實如此,Gson內部幫我們處理了關於陣列的情況,所以反序列化的情況就不說了,因為這不是我要說的是重點。我們想說的是單獨一個數組或者List的情況,其實這時候序列化還是一樣的,只是反序列化有所不同。
比如把下面的Json反序列化:
[
{
"bookName": "Thinking in Java",
"isbn": "6666",
"price": 78.0
},
{
"bookName": "程式設計之美",
"isbn": "8888",
"price": 63.0
}
]
如果你使用陣列的話和之前的一樣:
Book[] books = gson.fromJson(booksJson, Book[].class);
如果使用List的話,由於Java泛型擦除機制,執行時獲取不到型別,Gson設計一個TypeToken類解決這個問題,如下
Type bookType=new TypeToken<ArrayList<Book>>(){}.getType();
ArrayList<Book> books = gson.fromJson(booksJson, bookType);
這裡需要注意的是反序列化的Json陣列中的所有物件的型別必須一致,以便每一個都可以對映為同一個Java類。
使用Set
Type bookType=new TypeToken<Set<Book>>(){}.getType();
Set<Book> set=gson.fromJson(booksJson,bookType);
Map
仍然只說反序列化,比如下面一段Json
{
"content": "This is Content",
"title": "Hello",
"url": "http://pngfi.github.io"
}
你可封裝成一個Java類,你也可以將其對映為Map,比如
Type mapType=new TypeToken<Map<String,String>>(){}.getType();
Map<String,String> map=gson.fromJson(mapJson,mapType);
不知道你有沒有注意到我並沒有具體指定哪種型別的Map,只是指定了型別為Map介面,這時候預設情況下Gson幫我們生成LinkedTreeMap 物件,這是Gson自己封裝的類。List在不指定具體型別時生成ArrayList,Set預設為LinkedHashSet
Enum
比如說我定義了一個列舉Grade 表示學生成績等級,其中A,B,C,D為四個等級
public enum Grade {
A,
B,
C,
D
}
學生類程式碼如下:
public class Student {
public Grade grade;
public String name;
public int age;
public boolean isLOLPlayer;
}
這時候我們來序列化看一下結果:
Student student=new Student(Grade.A,"shilang",15,false);
Gson gson=new Gson();
String stuJSON=gson.toJson(student);
結果如下:
{
"age": 15,
"grade": "A",
"isLOLPlayer": false,
"name": "shilang"
}
你會發現Gson幫我們將grade序列化為A
反序列化:
關於反序列化Gson肯定能將上面的那段Json反序列化為Java物件。
自定義列舉例項名:
這裡要說明一中額外情況,就是有可能你不想讓B序列化為字串B,而是想序列化為1,你就可以通過新增下面的註解來實現。
public enum Grade {
A,
@SerializedName("1") B,
C,
D
}
關於@SerializedName註解請看下篇博文。