You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gson序列化Int键MutableMap后反序列化取值返回null问题排查

问题解答

1. JSON中能否存储Integer类型的Map键?

JSON规范明确要求所有键必须是字符串类型,所以无论你原Map的键是Integer还是其他数值类型,序列化成JSON后都会被自动转为字符串存储。但不需要必须改用String作为原Map的键,反序列化时可以通过配置让Gson把JSON中的字符串键转回Integer类型。

2. 你的序列化/反序列化写法问题

出现键被解析为String的核心原因,大概率是反序列化时没有指定Map的具体泛型类型,导致Gson因泛型擦除默认将键解析为String。

比如错误写法:

// 错误:直接用Map.class,泛型信息丢失,Gson默认解析为Map<String, ...>
Map map = gson.fromJson(jsonString, Map.class);

正确写法需要用TypeToken明确指定嵌套Map的泛型结构,避免泛型擦除:

// 序列化
MutableMap<Integer, MutableMap<Integer, MutableMap<Integer, Time>>> dataMap = ...;
Gson gson = new Gson();
String json = gson.toJson(dataMap);
getSharedPreferences("your_sp_name", MODE_PRIVATE)
    .edit()
    .putString("saved_data", json)
    .apply();

// 反序列化
String savedJson = getSharedPreferences("your_sp_name", MODE_PRIVATE)
    .getString("saved_data", "");
// 用TypeToken指定完整的泛型类型
Type dataType = new TypeToken<MutableMap<Integer, MutableMap<Integer, MutableMap<Integer, Time>>>>() {}.getType();
MutableMap<Integer, MutableMap<Integer, MutableMap<Integer, Time>>> restoredMap = gson.fromJson(savedJson, dataType);

3. 特殊情况的处理

如果默认Gson解析仍有问题(比如部分字符串键无法转为Integer),可以自定义TypeAdapter来强制将JSON字符串键转为Integer:

public class IntegerKeyMapTypeAdapter extends TypeAdapter<Map<Integer, Object>> {
    private final Gson gson = new Gson();

    @Override
    public void write(JsonWriter out, Map<Integer, Object> value) throws IOException {
        // 序列化时直接按正常逻辑处理,Gson会自动转Integer键为字符串
        gson.toJson(value, Map.class, out);
    }

    @Override
    public Map<Integer, Object> read(JsonReader in) throws IOException {
        Map<String, Object> stringKeyMap = gson.fromJson(in, new TypeToken<Map<String, Object>>() {}.getType());
        Map<Integer, Object> intKeyMap = new HashMap<>();
        for (Map.Entry<String, Object> entry : stringKeyMap.entrySet()) {
            try {
                Integer key = Integer.parseInt(entry.getKey());
                // 递归处理嵌套的Map
                if (entry.getValue() instanceof Map) {
                    entry.setValue(read(gson.newJsonReader(new StringReader(gson.toJson(entry.getValue())))));
                }
                intKeyMap.put(key, entry.getValue());
            } catch (NumberFormatException e) {
                // 处理无法转为Integer的键,可根据需求忽略或抛出异常
                e.printStackTrace();
            }
        }
        return intKeyMap;
    }
}

使用时需要在GsonBuilder中注册这个Adapter:

Gson gson = new GsonBuilder()
    .registerTypeAdapter(new TypeToken<Map<Integer, Object>>() {}.getType(), new IntegerKeyMapTypeAdapter())
    .create();

内容的提问来源于stack exchange,提问作者Layer891203

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 08:04:44