java - 使用 Gson 读取数据时避免从整数进行双重转换

标签 java gson typetoken

我在 aerospike 中使用 json 保存数据:

new Gson().toJson(data)

阅读时,我正在使用 typetoken:

Type type = new TypeToken<Map<String, Object>>() {
                        }.getType();
Map<String, Map<String, Object>> myMap = new Gson().fromJson(dataFromCache, type);

上述转换的问题是,所有整数都转换为 double 。我怎样才能停止转换?

最佳答案

这是 Gson 中的一个众所周知的问题。 默认情况下,Gson 总是将声明为 Object 的 JSON 数字反序列化为 Double,从而导致长整数值出现一些精度损失。 Object 序列化器/反序列化器不能被设计覆盖,所以你不能改变它的行为。 如果您可以将声明类型缩小到 Number,Gson 会将数字反序列化为 com.google.gson.internal.LazilyParsedNumber,它包含支持字符串并可以将其解析为任何“内置”数字类型(例如,longValue()doubleValue() 可以返回适当的值)。 如果您可以进一步缩小范围,效果会更好。 示例:

final String json = "[1,4,9]";
final Iterable<? extends Type> types = ImmutableList.of(
        new TypeToken<Collection<Object>>() {}.getType(),
        new TypeToken<Collection<Number>>() {}.getType(),
        new TypeToken<Collection<Integer>>() {}.getType()
);
for ( final Type type : types ) {
    System.out.print(type);
    System.out.print(": ");
    System.out.println();
    for ( final Object value : gson.<Iterable<?>>fromJson(json, type) ) {
        System.out.print('\t');
        System.out.print(value);
        System.out.print(' ');
        System.out.println(value.getClass());
    }
}

将产生以下输出:

java.util.Collection<java.lang.Object>: 
    1.0 class java.lang.Double
    4.0 class java.lang.Double
    9.0 class java.lang.Double
java.util.Collection<java.lang.Number>: 
    1 class com.google.gson.internal.LazilyParsedNumber
    4 class com.google.gson.internal.LazilyParsedNumber
    9 class com.google.gson.internal.LazilyParsedNumber
java.util.Collection<java.lang.Integer>: 
    1 class java.lang.Integer
    4 class java.lang.Integer
    9 class java.lang.Integer

简单来说,至少从 Gson 2.8.4 开始,您不能为 Object 执行此操作,但如果适合您,您可以指定更具体的类型。 我试图 fix问题,但修复仍处于预审状态。

关于java - 使用 Gson 读取数据时避免从整数进行双重转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50442637/

相关文章:

java - 调试 Java Web 应用程序的步骤是什么?

java - 直接读取 index.html 而不在 URL 中暴露其路径

java - 解析包含不同对象列表的 JSON 文件

java - 什么是类型和类型 token ?

generics - 如何在 gson typeToken 中使用泛型类型?

java - 从 MySQL 下载 Android App 数据的有效方法

java - 如何隐藏/删除 Wicket 中的分页导航器上的标签

java - Google GSON 不解析从 C# 网站中的 WebMethod 检索到的 Java 中的 JSON

android - “类的无参数构造函数不存在”,但它确实存在

java - 为泛型父类(super class)型的类型参数创建 TypeToken