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

使用Gson反序列化嵌套对象时保留Double值四位小数的问题

解决JSON反序列化时保留数值四位小数的问题

我最近碰到个棘手的问题:JSON反序列化时,原本带四位小数的数值(比如1800.0000)总是被自动截断成一位小数的格式(变成1800.0),怎么都没法保留原本的四位小数格式。

具体场景

  • 待反序列化的JSON字符串:
{"root": [{"paymentType": [{"listPrice": 1800.0000}]}]}
  • 现有的Java实体类结构:
public class Root { ... public List<Package> package; }
public class Package { ... public List<PaymentType> paymentType; }
public class PaymentType { ... public Double listPrice; }

我的期望是让listPrice保留四位小数格式,但目前反序列化后只能得到1800.0。

尝试过的无效方案

一开始我想着用Gson的自定义反序列化器来处理Double类型,代码如下:

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(new TypeToken<Double>() {}.getType(), new DoubleDeserializer());
Gson gson = gsonBuilder.create();
Root root = gson.fromJson(rawJson, Root.class);

对应的Double反序列化器实现:

public class DoubleDeserializer implements JsonDeserializer<Double> {
    @Override
    public Double deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        return json.getAsBigDecimal().setScale(4, RoundingMode.DOWN).doubleValue();
    }
}

结果发现这个反序列化器好像没作用在嵌套的PaymentType对象上,于是我又尝试给PaymentType类单独写反序列化器,但结果还是1800.0——后来才明白,问题出在getAsDouble()方法上,它会把1800.0000直接转换成1800.0,后续的格式化操作根本起不了作用。

最终可行的解决方案

多亏了@JoopEggen的提示,我把PaymentType类里的listPrice字段类型从Double改成了BigDecimal,然后用下面的代码来处理格式化:

BigDecimal formattedListPrice = paymentType.get("listPrice").getAsBigDecimal().setScale(4, RoundingMode.CEILING);

这样处理后,listPrice就能完美保留四位小数的格式了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 14:42:56