Избегайте двойного преобразования из целого числа при чтении данных с использованием Gson - PullRequest
0 голосов
/ 21 мая 2018

Я сохраняю данные с помощью json в aerospike:

new Gson().toJson(data)

Во время чтения я использую typetoken:

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

Проблема с приведенным выше преобразованием заключается в том, что все целые числа преобразованыв парном разряде.Как я могу остановить конвертацию?

1 Ответ

0 голосов
/ 21 мая 2018

Это известная проблема в 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, но вы можетеукажите более конкретный тип, если он вам подходит.Я пытался исправить проблему, но исправление все еще находится в состоянии предварительной проверки.

...