使用 moshi 反序列化时如何区分 long 和 double 值?

Sqr*_*764 6 java json moshi

我的目标是使用 JSON 格式同步任意行数据。由于我不知道行的确切方案(这是一种通用同步方法),因此我的数据模型显然必须依赖于“对象”。Map<String,Object>所以在Java中我将有一个与服务器同步的数组。

将这样的行转换为 JSON 会得到类似的结果

{{"string":"stringvalue"},{"double1":1234.567},{"double2":1234.0},{"long":1234}}
Run Code Online (Sandbox Code Playgroud)

到目前为止,一切都很好 - moshi 没有问题 - 一切都按预期进行。

现在的问题是:当我尝试使用 moshi 反序列化该 JSON 时,我得到“long”成员的双值。Moshi 将所有数字转换为双精度数。但不幸的是,并非所有数字都可以安全地转换为双精度数。非常大的整数(又名长整数)存在双精度数有限精度的问题。并且舍入效应也可能存在。

我向 moshi 提出了一个问题,但不幸的是该问题已关闭。也许是我表达得不够清楚。(第192期

JSON 没有整数的概念 - 只有数字和字符串。但是上面示例中的“double2”的微妙细节可能会导致我的问题的解决方案:
如果一个数字不包含小数点,那么它是一个整数,应该转换为长整型。

由于长整型无法无损转换为双精度,因此我需要一种方法在将值转换为双精度之前拦截解析器。但如何做到这一点呢?

Moshi 有 JsonAdapters 这个方便的概念 - 但不幸的是,我目前不知道如何在这种情况下使用它们:
这样的 JsonAdapter 的输入类型必须是 Object,因为我无法将生成的 double 转换为 long。所以我必须在解析器转换任何值之前拦截它。
但是如何从那里返回不止一种类型呢?(我必须从那里返回 String、Double 或 Long - 或者如果我可以将输入限制为仅数字,我至少必须返回 Long 或 Double。)

(我的后端是用 PHP 编写的,并自动生成所需的输出:整数不带小数点。)

Luk*_*kas 3

不改Moshi源码恐怕是不可能的。JSON 字符串源通过JsonReader将所有数字转换为双精度。我找不到改变这种行为的方法,因为所有子类都是受包保护的。