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

Dart/Flutter中jsonDecode解析Java Long丢失精度的解决方案咨询

在Dart中解析超大JSON数字避免精度丢失

方案1:利用jsonDecode的reviver参数全局处理

Dart内置的jsonDecode支持传入reviver回调函数,可在解析过程中拦截并修改每个键值对的结果。我们可以通过判断数值是否超过2^53-1(double类型能精确表示的最大整数),将这类超大数值转为BigInt或String,彻底避免精度丢失。

示例代码:

import 'dart:convert';

void main() {
  // 2^53 - 1,double类型可精确表示的最大整数
  const maxSafeInteger = 9007199254740991;
  var jsonStr = '''{
      "myList": [
        {
          "longNum": 1234567890123401352
        },
        {
          "longNum": 1234567890123450168
        },
        {
          "longNum": 1234567890123452213
        }
      ],
      "secondList": "Other stuff... Is regex an elegant solution to parse 1234567890123401352 here?"
    }''';
  
  Map parsedData = jsonDecode(jsonStr, reviver: (key, value) {
    if (value is num) {
      // 判断数值是否超出安全整数范围
      if (value > maxSafeInteger || value < -maxSafeInteger) {
        // 转为BigInt保留精度,也可替换为value.toString()转成字符串
        return BigInt.parse(value.toString());
      }
    }
    return value;
  });
  
  print(parsedData['myList'][0]['longNum']); // 精确输出:1234567890123401352
}

方案2:结合模型类与自定义转换器(适合结构化数据)

如果你的JSON有明确的业务结构,推荐使用json_serializable库配合自定义转换器,精准控制指定字段的解析逻辑,代码更易维护。

步骤1:定义转换器

import 'package:json_annotation/json_annotation.dart';

class BigIntConverter implements JsonConverter<BigInt, num> {
  const BigIntConverter();

  @override
  BigInt fromJson(num json) => BigInt.parse(json.toString());

  @override
  num toJson(BigInt object) => object.toInt(); // 若后端需接收字符串,可改为object.toString()
}

步骤2:编写模型类

part 'data_model.g.dart';

@JsonSerializable()
class ListItem {
  // 给需要解析为BigInt的字段添加转换器注解
  @BigIntConverter()
  final BigInt longNum;

  ListItem({required this.longNum});

  factory ListItem.fromJson(Map<String, dynamic> json) => _$ListItemFromJson(json);
  Map<String, dynamic> toJson() => _$ListItemToJson(this);
}

@JsonSerializable()
class DataModel {
  final List<ListItem> myList;
  final String secondList;

  DataModel({required this.myList, required this.secondList});

  factory DataModel.fromJson(Map<String, dynamic> json) => _$DataModelFromJson(json);
  Map<String, dynamic> toJson() => _$DataModelToJson(this);
}

步骤3:使用模型解析

import 'dart:convert';
import 'data_model.dart';

void main() {
  var jsonStr = '''{...}'''; // 你的目标JSON字符串
  var decodedJson = jsonDecode(jsonStr);
  var dataModel = DataModel.fromJson(decodedJson);
  
  print(dataModel.myList[0].longNum); // 精确输出原始数值
}

避坑提醒

  • 禁止用正则解析JSON字符串:JSON结构可能包含嵌套、字符串内的数字等复杂场景,正则极易误处理,引发难以排查的bug。
  • 若选择转为String,后续使用时需手动处理类型转换;BigInt支持直接进行数值运算,灵活性更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 11:43:24