我在 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/