使用 Gson 反序列化 Map<String, List<?>>

ViT*_*al- 5 java android json gson

我在服务器中序列化数据:

Gson gson = new Gson();
Map<String, List<?>> resultMap = BackendUpdateManager.getInstance()
    .getUpdates(timeHolder, shopIdInt, buyerIdInt);
gson.toJson(resultMap);
Run Code Online (Sandbox Code Playgroud)

并反序列化:

Gson gson = new Gson();
Map<String, List<?>> resultMap =  gson.fromJson(json,
    new TypeToken<Map<String, List<?>>>() {
    }.getType());
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试使用以下项目时Map

List<ProductCategory> productCategoryList = (List<ProductCategory>)updateMap.get(key);

for(ProductCategory productCategory : productCategoryList) {

}
Run Code Online (Sandbox Code Playgroud)

我得到错误:

造成的:java.lang.ClassCastException:com.google.gson.internal.LinkedTreeMap不能强制转换为com.example.model.entity.ProductCategory

如何修复此错误或以其他方式创建 Mapwith List<different classes>

我尝试使用 getter 和 setter 创建类,其中包含List不同类的 s 而不是Map<String, List<?>>并将其用于序列化和反序列化。但我正在寻找更好的方法。

dur*_*597 2

Gson 应该如何知道特定的 Json 字符串是 a ProductCategory?例如,如果 的定义ProductCategory是这样的:

package com.stackoverflow.vitvetal;  

public class ProductCategory {
    String name;
    String type;
}
Run Code Online (Sandbox Code Playgroud)

Json 是这样的:

{
    "name":"bananas",
    "type":"go-go"
}
Run Code Online (Sandbox Code Playgroud)

告诉 Gson 创建 a 实例的链接在哪里com.stackoverflow.vitvetal.ProductCategory

该链接不存在,因为您没有告诉 Gson。

所以 gson 所做的是,它创建了一个Map<String, String>看起来像

"name" -> "bananas"
"type" -> "go-go"
Run Code Online (Sandbox Code Playgroud)

如果您想做一些不同的事情,最简单的事情 - 但也是最不强大的 - 是在创建 ; 时完全指定参数化类型TypeToken。不允许使用通配符<?>

如果您需要做一些更强大的事情,例如创建具有更多对象种类的地图,您需要使用 a创建一个自定义反序列化器TypeAdapter<T>,它教 Gson 如何处理特定类型的对象。