无法将服务端响应转为Model类,Dart代码报错求解决
问题分析与解决:
type List<dynamic> is not a subtype of type List<Person> 你的问题核心在于泛型类PersonResponse的fromJSON方法没有正确将List<dynamic>中的每个元素转换为指定的泛型类型T。Dart的json.decode返回的是动态类型,当你直接把json["person"](本质是List<dynamic>)赋值给List<T> persons时,Dart无法自动把列表里的每个Map对象转换成Person实例——因为泛型在运行时会被类型擦除,PersonResponse并不知道如何把动态元素转成你想要的具体类型。
具体来说,你的PersonResponse.fromJSON只是直接赋值,完全没处理元素的类型转换,这就导致了类型不匹配的错误。
解决方案
我们需要给PersonResponse添加一个类型转换逻辑,把列表里的每个Map元素转换成对应的T实例,这里有两种实用的实现方式:
方式一:在fromJSON中传入转换函数
修改PersonResponse类,让它的构造函数接收一个转换函数,用来把单个Map转成T对象:
class PersonResponse<T> { List<T> persons; // 新增转换函数参数,负责将Map转为T PersonResponse.fromJSON(Map json, T Function(Map) convert) { // 遍历List<dynamic>,逐个转换为T后再转成List<T> this.persons = (json["person"] as List).map((item) => convert(item)).toList(); } }
然后在main函数中调用时,传入Person的构造函数作为转换逻辑:
void main() { var strJson = """{ "person": [ {"name": "Mahendra", "age": 28}, {"name": "Test", "age": 25} ] }"""; var data = json.decode(strJson); print("json: $data"); // 传入Person.fromJSON作为转换函数 var result = PersonResponse<Person>.fromJSON(data, (map) => Person.fromJSON(map)); print("result: ${result.persons}"); }
方式二:让Model类实现通用解析接口(更优雅)
定义一个抽象接口,让所有需要解析的Model类都实现它,这样PersonResponse可以更通用,不用每次都传转换函数:
// 定义抽象解析接口 abstract class JsonParsable { factory JsonParsable.fromJson(Map json) => throw UnimplementedError(); } // 让Person实现该接口 class Person implements JsonParsable { String name; int age; Person.fromJSON(Map json) { this.name = json["name"]; this.age = json["age"]; } // 实现接口的factory构造函数 factory Person.fromJson(Map json) => Person.fromJSON(json); } // 约束T必须是JsonParsable的子类 class PersonResponse<T extends JsonParsable> { List<T> persons; PersonResponse.fromJSON(Map json) { // 利用接口的fromJson方法批量转换元素 this.persons = (json["person"] as List).map((item) => T.fromJson(item as Map)).toList(); } }
此时main函数的调用会更简洁:
void main() { var strJson = """{ "person": [ {"name": "Mahendra", "age": 28}, {"name": "Test", "age": 25} ] }"""; var data = json.decode(strJson); print("json: $data"); var result = PersonResponse<Person>.fromJSON(data); print("result: ${result.persons}"); }
额外小建议
- 建议把
fromJSON改成fromJson(小写j),符合Dart官方的命名规范。 - 如果你的项目中有大量Model需要解析,推荐使用
json_serializable包自动生成解析代码,避免手动写逻辑出错,效率也更高。
内容的提问来源于stack exchange,提问作者Mahendra
相关产品推荐
相关产品推荐

