You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 17:54:04