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

Kotlin中如何定义包含String类型的密封类SealedLikeClass?

解决方案

Kotlin密封类无法直接将String作为子类,所以我们需要给String套一个包装类,同时把另外两种结构化对象定义为数据类,统一作为密封类的子类来实现类型分组。

1. 定义结构化value对应的数据类

先把JSON里两种带字段的对象单独定义成数据类:

// 对应含address和next的value对象
data class AddressNextData(
    val address: String,
    val next: String
)

// 对应含count和option的value对象
data class CountOptionData(
    val count: String,
    val option: String
)

2. 定义密封类SealedLikeClass

用密封类包裹三种value类型,字符串通过专属子类封装:

sealed class SealedLikeClass {
    // 包裹String类型的子类
    data class StringWrapper(val value: String) : SealedLikeClass()
    // 包裹AddressNextData的子类
    data class AddressNext(val value: AddressNextData) : SealedLikeClass()
    // 包裹CountOptionData的子类
    data class CountOption(val value: CountOptionData) : SealedLikeClass()
}

3. 修正Request结构(可选)

注意到你提供的JSON里data是数组,每个元素包含id和value,所以原Request定义需要调整为适配数组的结构:

data class Request(
    val data: List<DataItem>
)

// 数组中每个元素的结构
data class DataItem(
    val id: Int,
    val value: SealedLikeClass
)

4. JSON序列化/反序列化处理

如果需要和JSON互相转换,以Gson为例,需要自定义TypeAdapter来识别value类型并映射到对应子类:

class SealedLikeClassTypeAdapter : TypeAdapter<SealedLikeClass>() {
    override fun write(out: JsonWriter, value: SealedLikeClass?) {
        when (value) {
            is SealedLikeClass.StringWrapper -> out.value(value.value)
            is SealedLikeClass.AddressNext -> Gson().toJson(value.value, out)
            is SealedLikeClass.CountOption -> Gson().toJson(value.value, out)
            null -> out.nullValue()
        }
    }

    override fun read(`in`: JsonReader): SealedLikeClass {
        return when (`in`.peek()) {
            JsonToken.STRING -> {
                SealedLikeClass.StringWrapper(`in`.nextString())
            }
            JsonToken.BEGIN_OBJECT -> {
                val jsonObject = JsonParser.parseReader(`in`).asJsonObject
                if (jsonObject.has("address") && jsonObject.has("next")) {
                    SealedLikeClass.AddressNext(Gson().fromJson(jsonObject, AddressNextData::class.java))
                } else if (jsonObject.has("count") && jsonObject.has("option")) {
                    SealedLikeClass.CountOption(Gson().fromJson(jsonObject, CountOptionData::class.java))
                } else {
                    throw IllegalArgumentException("Unknown value type")
                }
            }
            else -> throw IllegalArgumentException("Unsupported JSON token")
        }
    }
}

使用时将适配器注册到Gson实例:

val gson = GsonBuilder()
    .registerTypeAdapter(SealedLikeClass::class.java, SealedLikeClassTypeAdapter())
    .create()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 12:15:41