GSON反序列化时如何将Object类型特殊浮点值转为Double类型
问题原因
原生Gson反序列Object类型字段时,由于标准JSON规范不支持Infinity、-Infinity、NaN这类非标准数字字面量,默认会把这些值识别为字符串类型,因此你的第二个相等断言会失败。
现有方案评估
你当前的实现是合理可行的,核心采用委托模式复用Gson原生的数组反序列化逻辑,仅对特殊浮点值做后置转换,避免了完全重写适配器的高维护成本,是性价比很高的实现方式。不过还可以做两处优化:
- 移除
JsonParser中间树转换逻辑,直接在流处理阶段完成判断,降低大数组场景下的内存和性能开销 - 可根据业务场景选择适配范围:如果仅需要处理
ValuesObject类下的Object[]字段,可以缩小适配范围,避免影响全局的Object[]反序列化逻辑
优化后实现代码
import com.google.gson.*; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; import java.io.IOException; class SpecialFloatObjectArrayTypeAdapterFactory implements TypeAdapterFactory { private SpecialFloatObjectArrayTypeAdapterFactory() {} public static SpecialFloatObjectArrayTypeAdapterFactory create() { return new SpecialFloatObjectArrayTypeAdapterFactory(); } @Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { // 仅处理Object[]类型,如果要缩小适配范围,可改为判断ValuesObject.class if (type.getRawType() != Object[].class) { return null; } TypeAdapter<Object[]> delegate = gson.getDelegateAdapter(this, TypeToken.get(Object[].class)); @SuppressWarnings("unchecked") TypeAdapter<T> adapter = (TypeAdapter<T>) new TypeAdapter<Object[]>() { @Override public void write(JsonWriter out, Object[] value) throws IOException { delegate.write(out, value); } @Override public Object[] read(JsonReader in) throws IOException { Object[] array = delegate.read(in); for (int i = 0; i < array.length; i++) { if (array[i] instanceof String s) { // Java 8及以下请替换为常规case break写法 switch (s) { case "Infinity", "-Infinity", "NaN" -> array[i] = Double.valueOf(s); } } } return array; } }.nullSafe(); // 自动处理空值,无需额外判空 return adapter; } }
注册方式
构造Gson实例时注册适配器工厂即可:
Gson gson = new GsonBuilder() .serializeSpecialFloatingPointValues() .registerTypeAdapterFactory(SpecialFloatObjectArrayTypeAdapterFactory.create()) .create();
内容的提问来源于stack exchange,提问作者doc
相关产品推荐
相关产品推荐

