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
相关产品推荐
相关产品推荐

