Gson通過藉助TypeToken獲取泛型引數的型別的方法

FrankYou發表於2018-03-22

轉載|

最近在使用Google的Gson包進行Json和Java物件之間的轉化,對於包含泛型的類的序列化和反序列化Gson也提供了很好的支援,感覺有點意思,就花時間研究了一下。

由於Java泛型的實現機制,使用了泛型的程式碼在執行期間相關的泛型引數的型別會被擦除,我們無法在執行期間獲知泛型引數的具體型別(所有的泛型型別在執行時都是Object型別)。

但是有的時候,我們確實需要獲知泛型引數的型別,比如將使用了泛型的Java程式碼序列化或者反序列化的時候,這個時候問題就變得比較棘手。

class Foo<T> {
T value;
}
Gson gson = new Gson();
Foo<Bar> foo = new Foo<Bar>();
gson.toJson(foo); // May not serialize foo.value correctly

gson.fromJson(json, foo.getClass()); // Fails to deserialize foo.value as Bar

 對於上面的類Foo<T>,由於在執行期間無法得知T的具體型別,對這個類的物件進行序列化和反序列化都不能正常進行。Gson通過藉助TypeToken類來解決這個問題。

TestGeneric<String> t = new TestGeneric<String>();
t.setValue("Alo");
Type type = new TypeToken<TestGeneric<String>>(){}.getType();

String gStr = GsonUtils.gson.toJson(t,type);
System.out.println(gStr);
TestGeneric t1 = GsonUtils.gson.fromJson(gStr, type);
System.out.println(t1.getValue());

TypeToken的使用非常簡單,如上面的程式碼,只要將需要獲取型別的泛型類作為TypeToken的泛型引數構造一個匿名的子類,就可以通過getType()方法獲取到我們使用的泛型類的泛型引數型別。

相關文章