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

如何修复@JsonSerializable中@JsonKey对象为Null的类型转换异常

解决Flutter中@JsonSerializable处理Null字段的序列化异常

问题原因

你的代码中shareInfo被定义为非空的ShareInfo类型,但当接口返回该字段为null时,自动生成的序列化代码会尝试将null强制转换为Map<String, dynamic>,触发type 'Null' is not a subtype of type 'Map<String, dynamic>'异常。

修复方法

方法1:将字段改为可空类型(推荐)

允许shareInfo为null,修改实体类字段类型为可空,让生成的代码自动处理null值:

import 'package:json_annotation/json_annotation.dart'; 
part 'jump.g.dart';

@JsonSerializable()
class Jump extends Object {
  @JsonKey(name: 'des', defaultValue: '')
  String des;
  @JsonKey(name: 'shareInfo')
  ShareInfo? shareInfo; // 改为可空类型
  Jump(this.des, this.shareInfo);
  factory Jump.fromJson(Map<String, dynamic> srcJson) => _$JumpFromJson(srcJson);
  Map<String, dynamic> toJson() => _$JumpToJson(this);
}

执行代码生成命令(flutter pub run build_runner build)后,生成的_$JumpFromJson会自动处理null:

Jump _$JumpFromJson(Map<String, dynamic> json) {
  return Jump(
    json['des'] as String? ?? '',
    json['shareInfo'] == null ? null : ShareInfo.fromJson(json['shareInfo'] as Map<String, dynamic>),
  );
}

方法2:设置默认实例(要求字段非空时使用)

如果业务要求shareInfo不能为null,可以给字段设置默认实例,前提是ShareInfo有默认构造函数:

  1. 给ShareInfo添加默认构造:
@JsonSerializable()
class ShareInfo {
  String? title;
  // 其他字段...
  
  ShareInfo({this.title});
  // 空实例构造函数
  ShareInfo.empty() : title = '';
  
  factory ShareInfo.fromJson(Map<String, dynamic> json) => _$ShareInfoFromJson(json);
}
  1. 修改Jump类的shareInfo字段注解:
@JsonSerializable()
class Jump extends Object {
  @JsonKey(name: 'des', defaultValue: '')
  String des;
  @JsonKey(name: 'shareInfo', defaultValue: ShareInfo.empty()) // 设置默认实例
  ShareInfo shareInfo; // 保持非空
  Jump(this.des, this.shareInfo);
  factory Jump.fromJson(Map<String, dynamic> srcJson) => _$JumpFromJson(srcJson);
  Map<String, dynamic> toJson() => _$JumpToJson(this);
}

重新生成代码后,当shareInfo为null时会自动使用ShareInfo.empty()实例,避免类型转换错误。

方法3:临时手动修改生成代码(不推荐)

如果不想重新生成代码,可临时修改jump.g.dart中的逻辑,但注意重新生成代码会覆盖此修改:

Jump _$JumpFromJson(Map<String, dynamic> json) {
  return Jump(
    json['des'] as String? ?? '',
    // 手动添加null判断
    json['shareInfo'] != null 
        ? ShareInfo.fromJson(json['shareInfo'] as Map<String, dynamic>)
        : ShareInfo.empty(), // 或者null(如果字段是可空类型)
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 11:03:39