解析含嵌套List的JSON到Dart对象及解决cast空指针错误
解决Dart嵌套JSON解析的NoSuchMethodError: 'cast'空指针问题
常见触发原因
- 工具生成的实体类中,列表字段的
cast调用未处理null值:比如(json['questions'] as List).cast<Question>(),如果JSON里该字段是null,as List返回null,再调用cast就会触发空指针。 - 嵌套层级的子实体类解析逻辑同样存在空值遗漏处理的情况,比如Question类里的ans列表解析没做判空。
- JSON字段和实体类字段不匹配(比如拼写错误),导致获取到null后执行
cast操作。
具体解决方案
1. 给列表字段添加空值判断与安全转换
修改实体类的fromJson方法,先判断字段是否为List类型,再通过map+toList转换,避免直接用cast:
class Video { final List<Question>? questions; Video({this.questions}); factory Video.fromJson(Map<String, dynamic> json) { return Video( questions: json['questions'] is List ? (json['questions'] as List).map((item) => Question.fromJson(item)).toList() : null, ); } }
Question类里的ans列表同理处理:
class Question { final List<Ans>? ans; Question({this.ans}); factory Question.fromJson(Map<String, dynamic> json) { return Question( ans: json['ans'] is List ? (json['ans'] as List).map((item) => Ans.fromJson(item)).toList() : null, ); } }
2. 强制使用空列表替代null(业务允许时)
如果确定JSON里的列表字段不会是null以外的非法类型,只是可能为空数组,可以直接用空列表兜底:
questions: (json['questions'] as List? ?? []).map((item) => Question.fromJson(item)).toList(),
这样即使字段为null,也会用空数组处理,不会触发空指针。
3. 核对JSON与实体类的字段匹配度
- 检查实体类字段名和JSON的key是否完全一致,比如JSON里是
answers,实体类写成ans就会导致获取到null。 - 确认JSON中列表字段的类型确实是数组,而非字符串或其他类型,避免
as List转换失败返回null。
4. 用json_serializable生成健壮解析代码(推荐)
如果工具生成的代码不靠谱,直接用官方推荐的json_serializable包自动生成解析逻辑:
- 在pubspec.yaml添加依赖:
dependencies: json_annotation: ^4.8.1 dev_dependencies: build_runner: ^2.4.4 json_serializable: ^6.7.0
- 编写带注解的实体类:
import 'package:json_annotation/json_annotation.dart'; part 'video.g.dart'; @JsonSerializable() class Video { final List<Question>? questions; Video({this.questions}); factory Video.fromJson(Map<String, dynamic> json) => _$VideoFromJson(json); Map<String, dynamic> toJson() => _$VideoToJson(this); } @JsonSerializable() class Question { final List<Ans>? ans; Question({this.ans}); factory Question.fromJson(Map<String, dynamic> json) => _$QuestionFromJson(json); Map<String, dynamic> toJson() => _$QuestionToJson(this); } @JsonSerializable() class Ans { final String? content; // 根据实际JSON字段调整 Ans({this.content}); factory Ans.fromJson(Map<String, dynamic> json) => _$AnsFromJson(json); Map<String, dynamic> toJson() => _$AnsToJson(this); }
- 运行命令生成解析代码:
dart pub run build_runner build
这种方式会自动处理空值、类型转换,避免手动写代码的疏漏。
内容的提问来源于stack exchange,提问作者PrimeTimeTran
相关产品推荐
相关产品推荐

