我在airospike中使用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);
上述转换的问题是,所有整数都转换为双精度数。如何停止转换?
答案 0 :(得分:3)
这是Gson中一个众所周知的问题。
默认情况下,Gson始终将声明为Object
的JSON数字反序列化为Double
,从而导致长整数值的某些精度损失。
Object
序列化程序/反序列化程序无法通过设计覆盖,因此您无法更改其行为。
如果您可以将声明类型缩小到Number
,Gson会将数字反序列化为com.google.gson.internal.LazilyParsedNumber
,其中包含一个支持字符串,并且可以将其解析为任何&#34;内置的&#34;懒惰的数字类型(例如,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这个问题,但修复程序仍处于预审状态。