Это известная проблема в Gson.По умолчанию Gson всегда десериализует числа JSON, объявленные от Object
до Double
, что приводит к некоторой потере точности для длинных целых значений.Object
сериализаторы / десериализаторы не могут быть переопределены по дизайну, поэтому вы не можете изменить его поведение.Если вы можете сузить тип объявления до Number
, Gson будет десериализовать числа до com.google.gson.internal.LazilyParsedNumber
, который содержит вспомогательную строку, и может анализировать его для любого «встроенного» числового типа (например, longValue()
и * 1007).* может вернуть соответствующее значение).Если вы можете сузить еще больше, это будет работать еще лучше.Пример:
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
Проще говоря, вы не можете сделать это в течение Object
s по крайней мере с Gson 2.8.4, но вы можетеукажите более конкретный тип, если он вам подходит.Я пытался исправить проблему, но исправление все еще находится в состоянии предварительной проверки.