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

如何在Kotlin中使用GSON对CHAR类型进行数字编解码?

Kotlin中使用GSON实现Char类型自定义编解码的解决方案

你的代码主要存在以下几个问题:

  • 反序列化器中生成Char实例后未返回,最终返回null,导致非空Char字段无法正确赋值,触发类型不匹配错误
  • 异常处理直接忽略错误,没有明确的错误反馈,不利于调试
  • 类型适配器的泛型声明不够严谨,增加了类型安全风险

以下是修正后的完整代码:

1. 数据类保持不变

data class Test(
    var typeChar: Char,
)

2. 修正后的Gson创建函数

private fun createGson(): Gson {
    val builder = GsonBuilder()

    // 注册Char类型的反序列化器
    builder.registerTypeAdapter(
        Char::class.java,
        JsonDeserializer<Char> { json, _, context ->
            val primitive = json.asJsonPrimitive
            return@JsonDeserializer when {
                primitive.isNumber -> primitive.asInt.toChar()
                primitive.isString -> {
                    val charStr = primitive.asString
                    if (charStr.length == 1) charStr[0]
                    else throw JsonParseException("无法将字符串\"$charStr\"解析为Char,必须是单个字符")
                }
                else -> throw JsonParseException("无法解析为Char类型,仅支持数字或单个字符字符串")
            }
        }
    )

    // 注册Char类型的序列化器
    builder.registerTypeAdapter(
        Char::class.java,
        JsonSerializer<Char> { value, _, _ ->
            JsonPrimitive(value.code)
        }
    )

    // 兼容Java的Character包装类型
    builder.registerTypeAdapter(
        Character::class.java,
        JsonDeserializer<Character> { json, _, context ->
            context.deserialize<Char>(json, Char::class.java)
        }
    )
    builder.registerTypeAdapter(
        Character::class.java,
        JsonSerializer<Character> { value, _, context ->
            context.serialize(value, Char::class.java)
        }
    )

    return builder.create()
}

关键修正点说明

  • 反序列化器:明确返回Char类型,支持从数字(Unicode编码)或单个字符字符串解析,遇到非法格式时抛出明确异常,便于调试定位问题
  • 序列化器:使用非空Char泛型,避免可空类型带来的潜在问题,将Char转换为对应的Unicode编码数字序列化
  • 兼容包装类型:额外注册Character类型适配器,确保混合Java/Kotlin代码场景下也能正常工作

测试示例

fun main() {
    val gson = createGson()

    // 序列化测试
    val testObj = Test('A')
    val jsonStr = gson.toJson(testObj)
    println("序列化结果:$jsonStr") // 输出:{"typeChar":65}

    // 反序列化测试(从数字)
    val fromNumber = gson.fromJson("{\"typeChar\":66}", Test::class.java)
    println("从数字反序列化:${fromNumber.typeChar}") // 输出:B

    // 反序列化测试(从单个字符字符串)
    val fromString = gson.fromJson("{\"typeChar\":\"C\"}", Test::class.java)
    println("从字符串反序列化:${fromString.typeChar}") // 输出:C
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 05:25:45