Gson 泛型處理方式

Gson 轉換博大精深,今天要探討的是泛型轉換處理方式

邦哥不會寫程式
程式裡有蟲
4 min readJun 2, 2020

--

Photo by John Schnobrich on Unsplash

單純的 Object Class

JSON Text 如下:

{
"Application": "application"
}

轉換成 Class 如下:

class Data {

@SerializedName("Application")
private String application;
}

利用 Gson 轉換方式如下:

Data data = new Gson().fromJson(jsonText, Data.class);

不太單純的 Object Class

JSON Text 如下:

{
"data" : [
{
"aaa": "aaa",
"bbb": "bbb"
},
{
"aaa": "aaa",
"bbb": "bbb"
}
]
}
}

轉換成 Class 如下:

class Data {

@SerializedName("data")
private List<Detail> data;
}class Detail {

@SerializedName("aaa")
private String aaa;
@SerializedName("bbb")
private String bbb;
}

利用 Gson 轉換方式如下:

Data data = new Gson().fromJson(jsonText, Data.class);

如果 data 陣列裡面放的是不同的物件,那我利用同一支 Class 寫泛型來轉換,就不用新增太多無謂的 Class了,否則就變成碼農啦!

泛型 Object Class

修改後的 Class 如下:

class Data<T> {

@SerializedName("data")
private List<T> details;
}

這時候轉換的方式要調整一下,先寫個 Utils method

public static <T> T jsonToObject(String jsonText, Type typeOfT) {
Gson gson = new Gson();
return gson.fromJson(jsonText, typeOfT);
}

接著利用下列程式碼進行轉換

Data<Detail> data = Utils.jsonToObject(result, new TypeToken<Data<Detail>>() {}.getType());

沒想到,天不從人願

取得的 details 竟然是 LinkedTreeMap,而且取值因為轉型的關係還會噴 Exception 怎麼辦呢?

那就從 LinkedTreeMap 下手吧!再來改寫一次 Class

class Data<T> {

@SerializedName("data")
private List<T> details;

public List<T> getDetail(Type typeOfT) {
final JsonArray jsonArray = new Gson().toJsonTree(details).getAsJsonArray();
return Utils.jsonToObject(jsonArray.toString(), typeOfT);
}
}

在 getDetail 的部分,先將 LinkedTreeMap 轉為 JsonText,再利用轉換後的 JsonText 轉成我們需要的泛型物件就可以了,轉換程式碼如下:

//取得 Data 
Data data = Utils.jsonToObject(result, new TypeToken<Data>() {}.getType());
//轉換為自己需要的泛型物件
final List<Detail> locations = data.getDetail(new TypeToken<List<Detail>>() {}.getType());

這樣子做就可以利用一支 Class 並利用泛型的方式做相同的事情啦!

參考來源

--

--