在真实项目中,一个对象可能同时包含金额、比率、坐标等多种浮点数据,它们对小数位数的要求完全不同。如果只用全局配置统一格式化,要么精度丢失,要么冗余。我们需要在 JSON 序列化时,为不同浮点字段指定独立的小数精度。

Java 中使用 Jackson 实现字段级精度
Jackson 提供了 @JsonSerialize 注解,可以针对单个字段使用自定义序列化器。下面写一个保留指定小数位的序列化器。
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.serializer.StdSerializer;
import java.io.IOException;
// 自定义浮点精度序列化器
public class RoundSerializer extends StdSerializer<Double> {
private int scale;
public RoundSerializer(int scale) {
super(Double.class);
this.scale = scale;
}
@Override
public void serialize(Double value, JsonGenerator gen, SerializerProvider provider) throws IOException {
if (value == null) {
gen.writeNull();
return;
}
double factor = Math.pow(10, scale);
double rounded = Math.round(value * factor) / factor;
gen.writeNumber(rounded);
}
}
在实体类里,对不同字段使用不同精度的序列化器:
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
public class Order {
@JsonSerialize(using = RoundSerializer.class) // 默认构造不适用,见下
// 实际应使用带参方式,下面用内部类示意
public double amount;
public static class Scale2 extends RoundSerializer {
public Scale2() { super(2); }
}
public static class Scale4 extends RoundSerializer {
public Scale4() { super(4); }
}
@JsonSerialize(using = Scale2.class)
public double price;
@JsonSerialize(using = Scale4.class)
public double rate;
}
Python 中灵活控制每个字段精度
Python 标准库 json 不直接支持字段注解,我们可以在 dumps 之前用字典处理,或者写自定义编码器。
import json
def custom_round(obj):
# 对特定字段保留不同精度
return {
'price': round(obj['price'], 2),
'rate': round(obj['rate'], 4),
'x': round(obj['x'], 6)
}
data = {'price': 12.3456, 'rate': 0.12345678, 'x': 3.1415926535}
out = custom_round(data)
print(json.dumps(out))
.NET 中使用 JsonConverter
通过继承 JsonConverter,可以给属性加特性指定精度。
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
public class DecimalPrecisionConverter : JsonConverter<double> {
private int _scale;
public DecimalPrecisionConverter(int scale) { _scale = scale; }
public override double Read(ref Utf8JsonReader reader, Type type, JsonSerializerOptions options) {
return reader.GetDouble();
}
public override void Write(Utf8JsonWriter writer, double value, JsonSerializerOptions options) {
writer.WriteNumberValue(Math.Round(value, _scale));
}
}
public class Model {
[JsonConverter(typeof(DecimalPrecisionConverter), 2)]
public double Amount { get; set; }
[JsonConverter(typeof(DecimalPrecisionConverter), 4)]
public double Rate { get; set; }
}
总结对比
| 语言 | 方案 | 粒度 |
|---|---|---|
| Java | 自定义 StdSerializer + 注解 | 字段级 |
| Python | 预处理或自定义 Encoder | 字段级 |
| .NET | JsonConverter 特性 | 字段级 |
无论哪种方式,核心思路都是把精度逻辑从全局配置移到字段描述上,从而让同一个对象里的浮点字段在 JSON 中呈现各自需要的小数位数。
JSON序列化浮点精度自定义序列化JacksonPython_json修改时间:2026-07-25 11:27:23