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

如何用Gson反序列化Jetpack Compose的Color类型?

解决Gson反序列化Compose Color内联值类的问题

问题根源

Compose的Color是JVM内联值类(@JvmInline value class Color(val value: ULong)),Gson默认会将其视为底层的ULong类型处理,直接绕过针对Color::class.java注册的适配器,导致自定义逻辑不生效;而错误注册Long类型适配器时,又会因类型不匹配抛出异常。

解决方案

以下两种方法均可在不修改字段类型的前提下实现需求:


方案一:全局注册Color类型的层次适配器

使用registerTypeHierarchyAdapter替代普通的registerTypeAdapter,让Gson正确识别内联值类并触发自定义适配器:

fun main() {
    val gson = GsonBuilder()
        // 注册Color类型的层次适配器
        .registerTypeHierarchyAdapter(Color::class.java, ColorAdapter())
        .create()
    
    // 注意JSON格式要规范,键名必须用双引号包裹
    val colors = gson.fromJson("{\"color\": \"#FFFFFF\"}", Colors::class.java)
    println(colors)
}

class ColorAdapter : TypeAdapter<Color>() {
    override fun write(out: JsonWriter?, value: Color?) {
        value?.let {
            out?.value(String.format("#%08X", it.value))
        }
    }

    override fun read(reader: JsonReader): Color {
        val colorHex = reader.nextString().removePrefix("#")
        // 将十六进制字符串转为ULong,适配Color的构造参数类型
        val colorValue = colorHex.toULong(radix = 16)
        return Color(colorValue)
    }
}

data class Colors(val color: Color)

方案二:在数据类字段上指定适配器

如果不需要全局适配,可直接在Color字段上添加@JsonAdapter注解,强制Gson使用自定义适配器:

import com.google.gson.annotations.JsonAdapter

data class Colors(
    @JsonAdapter(ColorAdapter::class)
    val color: Color
)

// 适配器和main函数逻辑同方案一

关键注意事项

  1. 必须使用符合标准的JSON格式,键名必须用双引号包裹(如{"color": "#FFFFFF"}而非{color: "#FFFFFF"})
  2. 适配器中要将十六进制字符串转为ULong,因为Color的构造参数是无符号长整型,避免类型不匹配
  3. 针对内联值类,registerTypeHierarchyAdapter比registerTypeAdapter更可靠,能让Gson正确识别目标类型

内容的提问来源于stack exchange,提问作者Милош Којадиновић

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 09:43:11