Java 使用gson在反序列化期间格式化嵌套对象中的双精度值

Java 使用gson在反序列化期间格式化嵌套对象中的双精度值,java,json,gson,Java,Json,Gson,试图实现从json反序列化时保留4个小数点格式。现在它只得到一个小数点,例如1800.0。这是需要反序列化的json字符串: { "root": [ { "paymentType": [ { "listPrice": 1800.0000 } ] } ] } 我有以下课程: public class Root { ... publ

试图实现从json反序列化时保留4个小数点格式。现在它只得到一个小数点,例如1800.0。这是需要反序列化的json字符串:

{
  "root": [
    {
      "paymentType": [
        {
          "listPrice": 1800.0000
        }
      ]
    }
  ]
}
我有以下课程:

public class Root {
  ...
  public List<Package> package;
}
我想将listPrice的格式设置为保留四个小数点。它现在被截断为.0

gson序列化代码:

GsonBuilder gsonBuilder = new GsonBuilder();

gsonBuilder.registerTypeAdapter(new TypeToken<Double>() {}.getType(), new DoubleDeserializer());
Gson gson = gsonBuilder.create();
Root root = gson.fromJson(rawJson, Root.class);
但得到同样的结果:1800.0。这是由于在getAsDouble()或json值1800.0000的任何其他解析方法中进行了转换。应用格式时,该值从一开始就是1800.0,这使得格式冗余。有什么办法对付这个吗

最终更新:通过将PaymentType和格式中listPrice的Double类型更改为BigDecimal类型来解决(感谢@JoopEggen),使用:

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

谢谢大家!

这回答了你的问题吗?没有拖行0的双精度浮点型与拖行0为无穷大的双精度浮点型相同。数学表示法与字符串(人类可读)表示法不同,我的意思是没有理由设置比例,然后获得双精度值,因为double没有比例参数,因此在转换过程中会丢失信息。从数学上讲,1800.0等于1800.00,等于1800.0000甚至1800.000000000。关注文本格式值得一提。无论json中的文本是什么,文本1.2345可能不是该值,而是带有一个小近似错误的近似值。由于浮点没有精度,只需切换到非常详细的BigDecimal。是的,而不是Double/Double。并且不使用双构造函数,而是使用新的BigDecimal(“1.8000”)来提供精度。
GsonBuilder gsonBuilder = new GsonBuilder();

gsonBuilder.registerTypeAdapter(new TypeToken<Double>() {}.getType(), new DoubleDeserializer());
Gson gson = gsonBuilder.create();
Root root = gson.fromJson(rawJson, Root.class);
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();
  }
}
public PaymentType deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException {
    JsonObject paymentType = json.getAsJsonObject();
    if (isValid(paymentType)) {
      double listPrice = paymentType.get("listPrice").getAsDouble();
      DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(Locale.ROOT);
      df.applyPattern("#0.0000");
      double formattedListPrice = Double.parseDouble(df.format(listPrice));
      PaymentType formattedPaymentType = new PaymentType();
      formattedPaymentType.listPrice = formattedListPrice;
      return formattedPaymentType;
    }
    return new Gson().fromJson(json, PaymentType.class);
  }
 BigDecimal formattedListPrice =
          paymentType.get("listPrice").getAsBigDecimal().setScale(4, RoundingMode.CEILING);