Flutter JSON反序列化单个对象成功 存入列表时类型报错求助
问题修复方案
错误根因
- 你提供的JSON文件末尾存在冗余逗号,第二个对象闭合大括号后多写了一个逗号,部分JSON解析器会将其识别为数组末尾多了一个
null元素,遍历到该元素调用County.fromJson时就会触发空类型错误 - County模型类的空安全逻辑存在疏漏:你定义的
name、capital都是非空String类型,但fromJson方法中直接读取JSON字段赋值,未做类型校验;同时toJson方法中多余判断了capital == null,和非空的字段定义冲突 subCounties字段未指定泛型类型,会埋下隐式类型转换的隐患- 原有业务代码的
initState方法缺失super.initState调用,属于Flutter生命周期方法的规范问题
修复步骤
1. 修正JSON文件
删除最后一个对象末尾的冗余逗号,修改后内容如下:
[ { "name": "Baringo", "capital": "Kabarnet", "code": 30, "sub_counties": [ "Baringo central", "Baringo north", "Baringo south", "Eldama ravine", "Mogotio", "Tiaty" ] }, { "name": "Bomet", "capital": "Bomet", "code": 36, "sub_counties": [ "Bomet central", "Bomet east", "Chepalungu", "Konoin", "Sotik" ] } ]
2. 修正County模型类
补充泛型声明,优化类型校验逻辑,修改后代码如下:
import 'dart:convert'; List<County> countyFromJson(String str) => List<County>.from(json.decode(str).map((x) => County.fromJson(x))); String countyToJson(List<County> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson()))); class County { String name; String capital; int code; List<String> subCounties; County({ required this.name, required this.capital, required this.code, required this.subCounties, }); factory County.fromJson(Map<String, dynamic> json) { return County( name: json["name"] as String, capital: json["capital"] as String, code: json["code"] as int, subCounties: List<String>.from(json["sub_counties"].map((x) => x)) ); } Map<String, dynamic> toJson() => { "name": name, "capital": capital, "code": code, "sub_counties": List<dynamic>.from(subCounties.map((x) => x)), }; }
3. 简化业务代码的转换逻辑
你已经定义了全局的countyFromJson转换方法,直接调用即可,不需要自己手写循环转换:
class _MyHomePageState extends State<MyHomePage> { String? _chosenSubCounty; List<County> counties = []; Future<String> getJson() async { final jsonResult = await rootBundle.loadString('assets/json_files/counties.json'); // 直接调用封装好的转换方法即可 counties = countyFromJson(jsonResult); print(counties); return jsonResult; } @override void initState() { super.initState(); getJson(); } @override Widget build(BuildContext context) {/* 原有业务逻辑保持不变 */} }
内容的提问来源于stack exchange,提问作者Zuher Abud Said
相关产品推荐
相关产品推荐

