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

Kotlin中JSON转TypeToken时出现NumberFormatException问题咨询

解决JSON反序列化时的NumberFormatException问题

根据你描述的场景,这个异常大概率是Date字段的序列化/反序列化格式不匹配,或者JSON中字段类型与实体类定义不一致导致的。下面一步步帮你定位和解决:

1. 先排查存储的JSON实际内容

首先把SharedPreferences里存的JSON字符串打印出来,明确字段的实际格式,这是定位问题的关键:

val storedJson = sharedPrefs?.getString("your_data_key", "")
Log.d("JSON_CHECK", "Stored JSON content: $storedJson")

重点看两个字段:

  • myNumber是带引号的字符串(比如"1234")还是纯数字(比如1234)?
  • myDate是数字时间戳(比如1699999999000)还是日期字符串(比如"2023-11-13")?

2. 统一Date字段的序列化/反序列化规则

默认情况下,Gson(假设你用的是Gson做JSON转换)会把Date转成数字时间戳,但如果反序列化时配置不一致,或者JSON中myDate是字符串格式,就会触发NumberFormatException。

建议给Gson配置固定的日期格式适配器,确保序列化和反序列化逻辑一致:

// 创建统一配置的Gson实例
val gson = GsonBuilder()
    .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") // 用ISO8601格式,也可以换成你需要的格式
    .create()

存储时用这个Gson:

val myDataList = arrayListOf<MyData>(...)
val json = gson.toJson(myDataList)
sharedPrefs.edit().putString("your_data_key", json).apply()

读取时也用同一个Gson:

private fun GetMyDataArray(): ArrayList<MyData>? {
    val json = sharedPrefs?.getString("your_data_key", null) ?: return null
    val type = object : TypeToken<ArrayList<MyData>>() {}.type
    return try {
        gson.fromJson(json, type)
    } catch (e: NumberFormatException) {
        Log.e("DESERIALIZE_ERROR", "解析错误:${e.message}", e)
        null // 或者根据业务需求做错误处理
    }
}

3. 检查myNumber字段的类型一致性

如果myNumber在JSON里是不带引号的纯数字,而你的实体类定义是String类型,Gson默认可以自动转换,但如果myNumber包含非数字字符(比如"1,234"),可能会触发异常。这种情况下,要确保存储时myNumber始终是合法的字符串格式,或者在实体类里做类型兼容处理。

4. 顺便修复Calendar的潜在问题

你设置日期的代码里,Calendar的月份是从0开始的(0=1月,11=12月),如果你的monthNumber是用户输入的1-12,那实际设置的月份会比预期大1,比如输入1(1月)会被设置成2月。建议调整成:

cal.set(year.toInt(), monthNumber - 1, day.toInt()) // 减1适配Calendar的月份规则

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:54:37