[英]Using generics with GSON
我正在使用GSON將JSON解碼為T類型的對象,例如
public T decode(String json) {
Gson gson = new Gson();
return gson.fromJson(json, new TypeToken<T>() {}.getType());
}
但是,這將返回異常-
java.lang.AssertionError:意外的類型。 期望以下類型之一:java.lang.reflect.ParameterizedType,java.lang.reflect.GenericArrayType,但得到:sun.reflect.generics.reflectiveObjects.TypeVariableImpl,類型標記為:T
我認為通過使用TypeToken可以避免Type Erasure。
我錯了嗎?
謝謝
首先,我看不到像這樣包裝Gson有什么用。
對於您的問題,有關泛型T
本身的信息在運行時不可用。 它已被刪除。 它僅在編譯時可用。 您想使用實際類型來參數化它,而不是像new TypeToken<List<String>>
。
如您所見,由於Java中缺少經過修飾的泛型(不可能執行T t = new T()
),因此Gson本身被迫使用TypeToken
方法。 否則,Gson會以一種更為優雅的方式做到這一點。
為了能夠傳遞實際的類型,您必須重新發明TypeToken
已經在做的事情。 這沒有任何意義:)只是重用它,或者直接使用Gson而不將其包裝在這樣的輔助類中。
我認為第一個答案並未指出實際的解決方案:您還必須將Class實例與T一起傳遞,如下所示:
public T decode(String json, Class<T> cls) {
Gson gson = new Gson();
return gson.fromJson(json, cls);
}
這是因為這里的“ T”是變量類型,而不是類型引用; 並且僅由編譯器用於添加隱式強制轉換和驗證類型兼容性。 但是,如果您通過實際課程,則可以使用; 編譯器將檢查類型兼容性以減少不匹配的機會。
或者,您可以輸入TypeToken並傳遞它; 但是TypeToken必須使用實型而不是類型變量構造; 類型變量在這里幾乎沒有用。 但是,如果您確實想包裝東西,則不希望調用者使用TypeToken(這是Gson類型)。
同樣的包裝機制也可以與您提到的Jackson之類的其他庫一起使用。
我對此的解決方案是使用json解析器並將其分解成碎片
public static <TT> PushObj<TT> fromJSON(String json, Class<TT> classType)
{
JsonObject jObj = new JsonParser().parse(json).getAsJsonObject();
String type = jObj.get("type").getAsString();
JsonObject job = jObj.get("object").getAsJsonObject();
TT obj = new Gson().fromJson(job, classType);
return new PushObj<TT>(type, obj);
}
對象結構為:{String:Type,Generic:Object}
變量是:jObj是傳入的字符串的JSONObject,而job是通用對象的JSONObject。
因此,我使用json解析器分別獲取類型和對象的反射。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.