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

Flutter json_serializable反序列化报Null非String子类型错误

问题根因

你碰到的_TypeError (type 'Null' is not a subtype of type 'String')错误,核心原因是接口返回的JSON数据里存在字段值为null的情况,但你定义的所有实体类字段全是非空类型,json_serializable自动生成的强转逻辑遇到null值时会直接抛出类型转换异常。
常用的公开国家信息接口里,capital(部分无固定首都的小国)、gini(无基尼系数统计的国家)、borders(无陆地邻国的岛国)、cioc、numericCode,还有嵌套类里的货币符号、小语种翻译、区域组织字段都有可能返回null,你当前的代码强制要求所有字段必须是非空的String/int/List/自定义对象,自然会触发报错。

修复方案

方案1:将可能为null的字段改为可空类型(适配真实接口返回,最稳妥)

给所有可能返回null的字段类型前加?标记为可空类型,同时去掉构造函数里这些字段的required关键字,修改完成后重新执行代码生成命令:

flutter pub run build_runner build --delete-conflicting-outputs

以Country类为例,修改后的参考代码:

@JsonSerializable()
class Country {
  final String name;
  final List<String>? topLevelDomain;
  final String alpha2Code;
  final String alpha3Code;
  final List<String>? callingCodes;
  final String? capital;
  final List<String>? altSpellings;
  final String region;
  final String? continent;
  final int population;
  final List<int>? latlng;
  final String? demonym;
  final int? area;
  final double? gini;
  final List<String>? timezones;
  final List<String>? borders;
  final String? nativeName;
  final String? numericCode;
  final List<Currencies>? currencies;
  final List<Languages>? languages;
  final Translations? translations;
  final List<String>? flags;
  final List<RegionalBlocs>? regionalBlocs;
  final String? cioc;
  final bool? independent;

  Country(
      {required this.name,
      this.topLevelDomain,
      required this.alpha2Code,
      required this.alpha3Code,
      this.callingCodes,
      this.capital,
      this.altSpellings,
      required this.region,
      this.continent,
      required this.population,
      this.latlng,
      this.demonym,
      this.area,
      this.gini,
      this.timezones,
      this.borders,
      this.nativeName,
      this.numericCode,
      this.currencies,
      this.languages,
      this.translations,
      this.flags,
      this.regionalBlocs,
      this.cioc,
      this.independent});

  factory Country.fromJson(Map<String, dynamic> json) =>
      _$CountryFromJson(json);

  Map<String, dynamic> toJson() => _$CountryToJson(this);
}

嵌套的Currencies、Languages、Translations、RegionalBlocs类按照同样规则修改即可,比如Currencies里的symbol字段部分小众货币没有对应符号会返回null,Translations里部分小语种翻译缺失也会返回null,都需要加可空标记。

方案2:给字段配置默认值,不使用可空类型

如果你不想在业务代码里处理空判断,可以用@JsonKey注解给可能为null的字段设置默认值,这样即使接口返回null,json_serializable会自动用默认值填充,不会抛类型错误:

// 示例:字符串类型字段默认空字符串,数组类型字段默认空数组
@JsonKey(defaultValue: '')
final String capital;
@JsonKey(defaultValue: [])
final List<String> borders;
@JsonKey(defaultValue: 0.0)
final double gini;

快速定位null字段技巧

如果不确定具体是哪个字段返回null,可以在异常抛出的代码行打debug断点,运行到断点时查看当前正在转换的JSON map里哪个key对应的value是null,优先修改对应字段即可。


内容的提问来源于stack exchange,提问作者Sledge BOUNDA

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:54:26