我注意到沒有一種簡單的包羅萬象(無 POJO)的方式來將(在 GSON 中)aJsonArray
轉換為List
. 我找到了一個使用 a 的示例,TypeToken
當我嘗試將其移至泛型方法時(我對我的 Java 泛型有點模糊),我發現了一些奇怪的行為JsonObject
并且LinkedTreeMap
感到困惑。請參見下面的示例:
public <T> List<T> jsonArrayToList(JsonArray array, Class<T> clazz) {
Gson GSON = new Gson();
Type listType = new TypeToken<List<T>>() {}.getType();
return GSON.fromJson(array,listType);
}
@Test
public void testGson() {
Gson GSON = new Gson();
String jsonString = "[ {key:\"foo\",value:\"bar\"}, {key:\"shoe\",value:\"car\"} ]";
JsonArray testArray = new JsonParser().parse(jsonString).getAsJsonArray();
Type listType = new TypeToken<List<JsonObject>>() {}.getType();
List<JsonObject> goodList = GSON.fromJson(testArray,listType);
List<JsonObject> badList = jsonArrayToList(testArray, JsonObject.class); // Actually a list of LinkedTreeMap?
System.out.println( goodList ); // [{"key":"foo","value":"bar"}, {"key":"shoe","value":"car"}]
System.out.println( badList ); // [{key=foo, value=bar}, {key=shoe, value=car}]
try {
long shoeCount = goodList.stream().filter(o -> o.get("key").getAsString().startsWith("sh")).count();
System.out.println( shoeCount ); // 1
} catch (Exception e) { System.out.println( e.getMessage() ); }
try {
long shoeCount = badList.stream().filter(o -> o.get("key").getAsString().startsWith("sh")).count();
System.out.println( shoeCount );
} catch (Exception e) {
System.out.println(e.getMessage()); // com.google.gson.internal.LinkedTreeMap cannot be cast to com.google.gson.JsonObject
}
}
我只是好奇為什么會發生這種情況和/或通用方法是否不正確。
uj5u.com熱心網友回復:
正如評論中所解釋的,由于 Java 型別擦除,無論值是什么,TypeToken<List<T>>
它實際上都是在運行時。當 Gson 被告知反序列化時,因為它使用與 JSON 資料相對應的 Java 型別,對于您的 JSON 物件(使用 Gson 的實作)。TypeToken<List<Object>>
T
Object
java.util.Map
LinkedTreeMap
因此,一般而言,您在創建 a 時永遠不應該使用任何型別變數TypeToken
(不幸的是 Gson 本身并不阻止這種用法)。
對于您的特定用例,您可以使用該方法TypeToken.getParameterized
。有了它,您可以使用在運行時指定的型別引數創建引數化型別。這是以編譯時缺少型別安全為代價的,因此您必須確保getParameterized
根據泛型型別(例如Map<K, V>
需要兩個型別引數)提供正確數量的引數,并且它們不會驗證型別變數。
以下是如何在您的方法中使用它jsonArrayToList
:
public <T> List<T> jsonArrayToList(JsonArray array, Class<T> clazz) {
Gson GSON = new Gson();
Type listType = TypeToken.getParameterized?(List.class, clazz).getType();
return GSON.fromJson(array,listType);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/470426.html
上一篇:在泛型宣告中解構有什么用?
下一篇:如何實作泛型介面?