gson 反序列化后整形变浮点问题

public static void main(String[] args) {
        GsonBuilder builder = new GsonBuilder();
        builder.setDateFormat("yyyy-MM-dd HH:mm:ss");
        builder.registerTypeAdapter(new TypeToken>(){}.getType(),new MapTypeAdapter());
        Gson gson = builder.create();
        String value = "{\"amount\":20000}";
        Map map = gson.fromJson(value, new TypeToken>() {
        }.getType());
        System.out.println(map.get("amount"));

        GsonBuilder builder2 = new GsonBuilder();
        builder2.setDateFormat("yyyy-MM-dd HH:mm:ss");
        Gson gson2 = builder2.create();
        Map map2 = gson2.fromJson(value, new TypeToken>() {
        }.getType());
        System.out.println(map2.get("amount"));
    }

如上代码 一个JSON转换成Map 然后值类型会出现问题 从整形数据变成浮点数 ,字符串则没有任何问题
执行结果如下

20000
20000.0

如上代码 问题已经解决 解决方案和原因介绍
com.google.gson.internal.bind.ObjectTypeAdapter 参考gson的源码的这个类
反序列化的时候 NUMBER类型 的时候 默认是按double处理的所以加上了浮点数的。0 然后模拟此类定制一个TypeAdapter 解决此问题就可以了

 public Object read(JsonReader in) throws IOException {
        JsonToken token = in.peek();
        switch(token) {
        case BEGIN_ARRAY:
            List list = new ArrayList();
            in.beginArray();

            while(in.hasNext()) {
                list.add(this.read(in));
            }

            in.endArray();
            return list;
        case BEGIN_OBJECT:
            Map map = new LinkedTreeMap();
            in.beginObject();

            while(in.hasNext()) {
                map.put(in.nextName(), this.read(in));
            }

            in.endObject();
            return map;
        case STRING:
            return in.nextString();
            // NUMBER 值类型重写下方法  把不需要是浮点数的修改一下解析返回值即可
        case NUMBER:
            return in.nextDouble();
        case BOOLEAN:
            return in.nextBoolean();
        case NULL:
            in.nextNull();
            return null;
        default:
            throw new IllegalStateException();
        }
    }
 
  

要注意的是 builder.registerTypeAdapter(new TypeToken>(){}.getType(),new MapTypeAdapter());
这段代码 注册的时候 一定要与反序列化的类型一致否则匹配不上 会导致重写数据没有生效,检查是否生效的方法
com.google.gson.Gson#fromJson(com.google.gson.stream.JsonReader, java.lang.reflect.Type) 参考源码这个方法

    public  T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
        boolean isEmpty = true;
        boolean oldLenient = reader.isLenient();
        reader.setLenient(true);

        TypeAdapter typeAdapter;
        try {
            try {
                reader.peek();
                isEmpty = false;
//                这个位置检查看下获取到的typeAdapter  是否是自己 重写的那个 
                TypeToken typeToken = TypeToken.get(typeOfT);
                typeAdapter = this.getAdapter(typeToken);
                T object = typeAdapter.read(reader);
                Object var8 = object;
                return var8;
            } catch (EOFException var15) {
                if (!isEmpty) {
                    throw new JsonSyntaxException(var15);
                }
            } catch (IllegalStateException var16) {
                throw new JsonSyntaxException(var16);
            } catch (IOException var17) {
                throw new JsonSyntaxException(var17);
            } catch (AssertionError var18) {
                throw new AssertionError("AssertionError (GSON 2.8.5): " + var18.getMessage(), var18);
            }

            typeAdapter = null;
        } finally {
            reader.setLenient(oldLenient);
        }

        return typeAdapter;
    }

你可能感兴趣的:(java,java,gson,.0,反序列化)