
本文详解 moshi 的 polymorphicjsonadapterfactory 在处理 `map
在使用 Moshi 进行多态 JSON 反序列化时,PolymorphicJsonAdapterFactory 能够根据 JSON 中的 type 字段(如 "type": "User")自动将数据映射为对应子类实例。但当目标类型涉及嵌套泛型结构(例如 Map
根本原因在于:PolymorphicJsonAdapterFactory 仅作用于其注册的基类(如 Animal.class)及其直接使用场景。当该基类出现在嵌套泛型中(如 List
// ❌ 错误:将 List.class 和 baseType 并列作为 Map 的类型参数 ParameterizedType type = Types.newParameterizedType(Map.class, String.class, List.class, baseType);
等价于 Map
✅ 正确做法是使用 Types.newParameterizedType() 逐层构建嵌套类型,确保 List extends T> 本身作为一个完整的 ParameterizedType 传入 Map:
private staticMap > deserializeNestedPolymorphic( Class baseType, List > subclasses, String json) { // 构建多态工厂(支持 Animal → Dog/Cat) PolymorphicJsonAdapterFactory factory = PolymorphicJsonAdapterFactory.of(baseType, "type"); for (Class extends T> subclass : subclasses) { factory = factory.withSubtype(subclass, subclass.getSimpleName()); } // ✅ 关键修正:正确构造嵌套类型 Map > ParameterizedType listType = Types.newParameterizedType(List.class, baseType); ParameterizedType mapType = Types.newParameterizedType(Map.class, String.class, listType); Moshi moshi = new Moshi.Builder().add(factory).build(); JsonAdapter
? 提示:Types 是 Moshi 自带的 com.squareup.moshi.Types 工具类,专用于运行时泛型类型构造,不可替换为 java.lang.reflect.Type 的其他实现。
此外,还需确保 JSON 结构与类型定义严格匹配。例如,针对 Map
{
"pets": [
{ "type": "Dog", "name": "Buddy", "barkVolume": 8 },
{ "type": "Cat", "name": "Luna", "livesLeft": 7 }
],
"zoo": [
{ "type": "Dog", "name": "Rex", "barkVolume": 9 }
]
}此时调用上述方法将返回 Map,其 value 是 List
总结:Moshi 多态反序列化在嵌套场景下失效,几乎总是源于 ParameterizedType 构造不完整。牢记原则——每一层泛型都必须用 Types.newParameterizedType() 显式封装,从最内层(如 List









