Flutter DataModel报非空实例字段未初始化错误如何解决
问题原因
这是Dart空安全机制的强制要求:非可空类型的实例字段,必须在构造函数体执行前完成初始化。你当前使用的
DataModel.fromJson构造是在函数体内给字段赋值,不符合空安全的初始化校验规则,因此触发报错。
解决方案
方案1:调整fromJson构造为初始化列表形式(最推荐)
这种方式不需要修改字段定义,也不需要用late,完全符合空安全校验规则:
String buttonLetter; int buttonHeight; int buttonWidth; int buttonStartingXpoint; int buttonStartingYpoint; DataModel({ required this.buttonLetter, required this.buttonHeight, required this.buttonWidth, required this.buttonStartingXpoint, required this.buttonStartingYpoint }); // 调整为初始化列表形式赋值,同时对json取值做类型强转 DataModel.fromJson(Map<String, dynamic> json) : buttonLetter = json['Button_letter'] as String, buttonHeight = json['Button_height'] as int, buttonWidth = json['Button_width'] as int, buttonStartingXpoint = json['Button_Starting_xpoint'] as int, buttonStartingYpoint = json['Button_Starting_ypoint'] as int; Map<String, dynamic> toJson() { final Map<String, dynamic> data = <String, dynamic>{}; data['Button_letter'] = buttonLetter; data['Button_height'] = buttonHeight; data['Button_width'] = buttonWidth; data['Button_Starting_xpoint'] = buttonStartingXpoint; data['Button_Starting_ypoint'] = buttonStartingYpoint; return data; }
把赋值逻辑移到构造函数名后的冒号之后,就属于构造函数初始化阶段的赋值,能通过空安全校验。
方案2:正确使用late关键字
如果你要使用late,需要确保所有字段在第一次被访问前一定会被赋值,同时对json取出的值做类型强转:
// 给所有非空字段加late late String buttonLetter; late int buttonHeight; late int buttonWidth; late int buttonStartingXpoint; late int buttonStartingYpoint; DataModel({ required this.buttonLetter, required this.buttonHeight, required this.buttonWidth, required this.buttonStartingXpoint, required this.buttonStartingYpoint }); DataModel.fromJson(Map<String, dynamic> json) { buttonLetter = json['Button_letter'] as String; buttonHeight = json['Button_height'] as int; buttonWidth = json['Button_width'] as int; buttonStartingXpoint = json['Button_Starting_xpoint'] as int; buttonStartingYpoint = json['Button_Starting_ypoint'] as int; } // toJson部分无需修改
注意:如果后续出现json对应字段为null的情况,用late会触发运行时崩溃,所以优先选择方案1。
方案3:字段改为可空类型(适配后端可能返回空的场景)
如果接口返回的对应字段可能为null,可以把字段定义为可空类型,也可以额外设置默认值避免使用时频繁判空:
// 字段后加?声明为可空,也可以直接设置默认值如 int buttonHeight = 0; String? buttonLetter; int? buttonHeight; int? buttonWidth; int? buttonStartingXpoint; int? buttonStartingYpoint; DataModel({ this.buttonLetter, this.buttonHeight, this.buttonWidth, this.buttonStartingXpoint, this.buttonStartingYpoint }); DataModel.fromJson(Map<String, dynamic> json) { buttonLetter = json['Button_letter'] as String?; buttonHeight = json['Button_height'] as int?; buttonWidth = json['Button_width'] as int?; buttonStartingXpoint = json['Button_Starting_xpoint'] as int?; buttonStartingYpoint = json['Button_Starting_ypoint'] as int?; }
这种方式不需要加late,也能通过空安全校验,使用字段时可以结合??运算符设置 fallback 值。
内容的提问来源于stack exchange,提问作者Oni Sama
相关产品推荐
相关产品推荐

